blob: b93464ac3517f4128ae1af4b35f7253f1d769e1f [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth address family and sockets. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
Marcel Holtmannffcecac2013-10-17 17:24:18 -070028#include <linux/debugfs.h>
Marcel Holtmann9e8305b2016-08-30 05:00:35 +020029#include <linux/stringify.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010030#include <linux/sched/signal.h>
31
Marcel Holtmann3241ad82008-07-14 20:13:50 +020032#include <asm/ioctls.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#include <net/bluetooth/bluetooth.h>
Masatake YAMATO256a06c2012-07-26 01:26:32 +090035#include <linux/proc_fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Marcel Holtmanne64c97b2016-07-21 14:12:41 +020037#include "leds.h"
Marcel Holtmannee485292014-12-29 20:48:35 -080038#include "selftest.h"
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/* Bluetooth sockets */
Luiz Augusto von Dentzccf74f22020-01-16 15:55:57 -080041#define BT_MAX_PROTO (BTPROTO_LAST + 1)
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000042static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010043static DEFINE_RWLOCK(bt_proto_lock);
Dave Young68845cb2008-04-01 23:58:35 -070044
Dave Young68845cb2008-04-01 23:58:35 -070045static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070046static const char *const bt_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070047 "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
48 "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
49 "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
50 "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
51 "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
52 "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
53 "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
54 "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
Luiz Augusto von Dentzccf74f22020-01-16 15:55:57 -080055 "sk_lock-AF_BLUETOOTH-BTPROTO_ISO",
Dave Young68845cb2008-04-01 23:58:35 -070056};
57
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010058static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
Jan Engelhardt36cbd3d2009-08-05 10:42:58 -070059static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
Dave Young68845cb2008-04-01 23:58:35 -070060 "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
61 "slock-AF_BLUETOOTH-BTPROTO_HCI",
62 "slock-AF_BLUETOOTH-BTPROTO_SCO",
63 "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
64 "slock-AF_BLUETOOTH-BTPROTO_BNEP",
65 "slock-AF_BLUETOOTH-BTPROTO_CMTP",
66 "slock-AF_BLUETOOTH-BTPROTO_HIDP",
67 "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
Luiz Augusto von Dentzccf74f22020-01-16 15:55:57 -080068 "slock-AF_BLUETOOTH-BTPROTO_ISO",
Dave Young68845cb2008-04-01 23:58:35 -070069};
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010070
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020071void bt_sock_reclassify_lock(struct sock *sk, int proto)
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010072{
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020073 BUG_ON(!sk);
Hannes Frederic Sowafafc4e12016-04-08 15:11:27 +020074 BUG_ON(!sock_allow_reclassification(sk));
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010075
76 sock_lock_init_class_and_name(sk,
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +090077 bt_slock_key_strings[proto], &bt_slock_key[proto],
78 bt_key_strings[proto], &bt_lock_key[proto]);
Marcel Holtmanndb7aa1c2008-11-30 12:17:19 +010079}
Octavian Purdilab5a30dd2012-01-22 00:28:34 +020080EXPORT_SYMBOL(bt_sock_reclassify_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Stephen Hemmingerec1b4cf2009-10-05 05:58:39 +000082int bt_sock_register(int proto, const struct net_proto_family *ops)
Linus Torvalds1da177e2005-04-16 15:20:36 -070083{
Marcel Holtmann74da6262006-10-15 17:31:14 +020084 int err = 0;
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 if (proto < 0 || proto >= BT_MAX_PROTO)
87 return -EINVAL;
88
Marcel Holtmann74da6262006-10-15 17:31:14 +020089 write_lock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Marcel Holtmann74da6262006-10-15 17:31:14 +020091 if (bt_proto[proto])
92 err = -EEXIST;
93 else
94 bt_proto[proto] = ops;
95
96 write_unlock(&bt_proto_lock);
97
98 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099}
100EXPORT_SYMBOL(bt_sock_register);
101
David Herrmannbe9f97f2013-02-24 19:36:52 +0100102void bt_sock_unregister(int proto)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103{
104 if (proto < 0 || proto >= BT_MAX_PROTO)
David Herrmannbe9f97f2013-02-24 19:36:52 +0100105 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Marcel Holtmann74da6262006-10-15 17:31:14 +0200107 write_lock(&bt_proto_lock);
David Herrmannbe9f97f2013-02-24 19:36:52 +0100108 bt_proto[proto] = NULL;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200109 write_unlock(&bt_proto_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110}
111EXPORT_SYMBOL(bt_sock_unregister);
112
Eric Paris3f378b682009-11-05 22:18:14 -0800113static int bt_sock_create(struct net *net, struct socket *sock, int proto,
114 int kern)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115{
Marcel Holtmann74da6262006-10-15 17:31:14 +0200116 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Eric W. Biederman1b8d7ae2007-10-08 23:24:22 -0700118 if (net != &init_net)
119 return -EAFNOSUPPORT;
120
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 if (proto < 0 || proto >= BT_MAX_PROTO)
122 return -EINVAL;
123
Johannes Berg95a5afc2008-10-16 15:24:51 -0700124 if (!bt_proto[proto])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 request_module("bt-proto-%d", proto);
Marcel Holtmann74da6262006-10-15 17:31:14 +0200126
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 err = -EPROTONOSUPPORT;
Marcel Holtmann74da6262006-10-15 17:31:14 +0200128
129 read_lock(&bt_proto_lock);
130
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
Eric Paris3f378b682009-11-05 22:18:14 -0800132 err = bt_proto[proto]->create(net, sock, proto, kern);
Octavian Purdilab5a30dd2012-01-22 00:28:34 +0200133 if (!err)
134 bt_sock_reclassify_lock(sock->sk, proto);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 module_put(bt_proto[proto]->owner);
136 }
Marcel Holtmann74da6262006-10-15 17:31:14 +0200137
138 read_unlock(&bt_proto_lock);
139
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900140 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141}
142
Luiz Augusto von Dentz6bfa2732023-05-25 16:46:41 -0700143struct sock *bt_sock_alloc(struct net *net, struct socket *sock,
144 struct proto *prot, int proto, gfp_t prio, int kern)
145{
146 struct sock *sk;
147
148 sk = sk_alloc(net, PF_BLUETOOTH, prio, prot, kern);
149 if (!sk)
150 return NULL;
151
152 sock_init_data(sock, sk);
153 INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
154
155 sock_reset_flag(sk, SOCK_ZAPPED);
156
157 sk->sk_protocol = proto;
158 sk->sk_state = BT_OPEN;
159
Luiz Augusto von Dentz464c7022023-05-25 16:46:42 -0700160 /* Init peer information so it can be properly monitored */
161 if (!kern) {
162 spin_lock(&sk->sk_peer_lock);
163 sk->sk_peer_pid = get_pid(task_tgid(current));
164 sk->sk_peer_cred = get_current_cred();
165 spin_unlock(&sk->sk_peer_lock);
166 }
167
Luiz Augusto von Dentz6bfa2732023-05-25 16:46:41 -0700168 return sk;
169}
170EXPORT_SYMBOL(bt_sock_alloc);
171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
173{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200174 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 sk_add_node(sk, &l->head);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200176 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177}
178EXPORT_SYMBOL(bt_sock_link);
179
180void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
181{
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200182 write_lock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 sk_del_node_init(sk);
Gustavo F. Padovan94f5bfb2011-12-27 15:28:48 -0200184 write_unlock(&l->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185}
186EXPORT_SYMBOL(bt_sock_unlink);
187
Matthias Kaehlckec4f56272019-01-02 16:11:20 -0800188void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189{
Luiz Augusto von Dentz464c7022023-05-25 16:46:42 -0700190 const struct cred *old_cred;
191 struct pid *old_pid;
192
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 BT_DBG("parent %p, sk %p", parent, sk);
194
195 sock_hold(sk);
Matthias Kaehlckec4f56272019-01-02 16:11:20 -0800196
197 if (bh)
198 bh_lock_sock_nested(sk);
199 else
200 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
201
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
203 bt_sk(sk)->parent = parent;
Matthias Kaehlckec4f56272019-01-02 16:11:20 -0800204
Luiz Augusto von Dentz464c7022023-05-25 16:46:42 -0700205 /* Copy credentials from parent since for incoming connections the
206 * socket is allocated by the kernel.
207 */
208 spin_lock(&sk->sk_peer_lock);
209 old_pid = sk->sk_peer_pid;
210 old_cred = sk->sk_peer_cred;
211 sk->sk_peer_pid = get_pid(parent->sk_peer_pid);
212 sk->sk_peer_cred = get_cred(parent->sk_peer_cred);
213 spin_unlock(&sk->sk_peer_lock);
214
215 put_pid(old_pid);
216 put_cred(old_cred);
217
Matthias Kaehlckec4f56272019-01-02 16:11:20 -0800218 if (bh)
219 bh_unlock_sock(sk);
220 else
221 release_sock(sk);
222
Eric Dumazet7976a112019-11-05 14:11:52 -0800223 sk_acceptq_added(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224}
225EXPORT_SYMBOL(bt_accept_enqueue);
226
Dean Jenkins27bfbc22017-03-10 11:34:46 +0000227/* Calling function must hold the sk lock.
228 * bt_sk(sk)->parent must be non-NULL meaning sk is in the parent list.
229 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230void bt_accept_unlink(struct sock *sk)
231{
232 BT_DBG("sk %p state %d", sk, sk->sk_state);
233
234 list_del_init(&bt_sk(sk)->accept_q);
Eric Dumazet7976a112019-11-05 14:11:52 -0800235 sk_acceptq_removed(bt_sk(sk)->parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 bt_sk(sk)->parent = NULL;
237 sock_put(sk);
238}
239EXPORT_SYMBOL(bt_accept_unlink);
240
241struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
242{
Geliang Tang7eb74042015-12-18 23:33:25 +0800243 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 struct sock *sk;
245
246 BT_DBG("parent %p", parent);
247
Dean Jenkins27bfbc22017-03-10 11:34:46 +0000248restart:
Geliang Tang7eb74042015-12-18 23:33:25 +0800249 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
250 sk = (struct sock *)s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
Dean Jenkins27bfbc22017-03-10 11:34:46 +0000252 /* Prevent early freeing of sk due to unlink and sock_kill */
253 sock_hold(sk);
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200254 lock_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255
Dean Jenkins27bfbc22017-03-10 11:34:46 +0000256 /* Check sk has not already been unlinked via
257 * bt_accept_unlink() due to serialisation caused by sk locking
258 */
259 if (!bt_sk(sk)->parent) {
260 BT_DBG("sk %p, already unlinked", sk);
261 release_sock(sk);
262 sock_put(sk);
263
264 /* Restart the loop as sk is no longer in the list
265 * and also avoid a potential infinite loop because
266 * list_for_each_entry_safe() is not thread safe.
267 */
268 goto restart;
269 }
270
271 /* sk is safely in the parent list so reduce reference count */
272 sock_put(sk);
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 /* FIXME: Is this check still needed */
275 if (sk->sk_state == BT_CLOSED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 bt_accept_unlink(sk);
Yichen Zhao1a11ec892015-12-01 11:11:01 -0800277 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 continue;
279 }
280
Marcel Holtmannc4f912e2009-01-15 21:52:16 +0100281 if (sk->sk_state == BT_CONNECTED || !newsock ||
Vinicius Costa Gomesd0609912012-05-31 22:53:39 -0300282 test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 bt_accept_unlink(sk);
284 if (newsock)
285 sock_graft(sk, newsock);
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200286
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200287 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 return sk;
289 }
290
Gustavo F. Padovan8a154a82011-12-20 17:15:56 -0200291 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 }
Andrei Emeltchenkod37f50e2011-01-24 10:53:24 +0200293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 return NULL;
295}
296EXPORT_SYMBOL(bt_accept_dequeue);
297
Ying Xue1b784142015-03-02 15:37:48 +0800298int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
299 int flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 struct sock *sk = sock->sk;
302 struct sk_buff *skb;
303 size_t copied;
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500304 size_t skblen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 int err;
306
Marcel Holtmanna418b892008-11-30 12:17:28 +0100307 BT_DBG("sock %p sk %p len %zu", sock, sk, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
Marcel Holtmannd94a6102015-10-25 22:45:18 +0100309 if (flags & MSG_OOB)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 return -EOPNOTSUPP;
311
Hyunwoo Kim2e07e832023-12-09 05:55:18 -0500312 lock_sock(sk);
313
Oliver Hartkoppf4b41f02022-04-04 18:30:22 +0200314 skb = skb_recv_datagram(sk, flags, &err);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200315 if (!skb) {
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100316 if (sk->sk_shutdown & RCV_SHUTDOWN)
Hyunwoo Kim2e07e832023-12-09 05:55:18 -0500317 err = 0;
Hannes Frederic Sowaf3d33422013-11-21 03:14:22 +0100318
Hyunwoo Kim2e07e832023-12-09 05:55:18 -0500319 release_sock(sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 return err;
321 }
322
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500323 skblen = skb->len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 copied = skb->len;
325 if (len < copied) {
326 msg->msg_flags |= MSG_TRUNC;
327 copied = len;
328 }
329
Arnaldo Carvalho de Melobadff6d2007-03-13 13:06:52 -0300330 skb_reset_transport_header(skb);
David S. Miller51f3d022014-11-05 16:46:40 -0500331 err = skb_copy_datagram_msg(skb, 0, msg, copied);
Marcel Holtmannd9763692013-10-13 12:55:28 -0700332 if (err == 0) {
Erin MacNeil6fd1d512022-04-27 16:02:37 -0400333 sock_recv_cmsgs(msg, sk, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Ezequiel Garcia9dcbc312016-12-29 09:51:19 -0300335 if (msg->msg_name && bt_sk(sk)->skb_msg_name)
Marcel Holtmannd9763692013-10-13 12:55:28 -0700336 bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
337 &msg->msg_namelen);
Alain Michaud00398e12020-06-11 19:50:41 +0000338
Luiz Augusto von Dentz3f19ffb2023-07-13 13:41:31 -0700339 if (test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags)) {
340 u8 pkt_status = hci_skb_pkt_status(skb);
341
342 put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
343 sizeof(pkt_status), &pkt_status);
344 }
Marcel Holtmannd9763692013-10-13 12:55:28 -0700345 }
346
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 skb_free_datagram(sk, skb);
348
Hyunwoo Kim2e07e832023-12-09 05:55:18 -0500349 release_sock(sk);
350
Luiz Augusto von Dentz90a56f72016-08-12 15:11:28 +0300351 if (flags & MSG_TRUNC)
Denis Kenziorb5f34f92016-06-27 11:01:12 -0500352 copied = skblen;
353
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 return err ? : copied;
355}
356EXPORT_SYMBOL(bt_sock_recvmsg);
357
Mat Martineau796c86e2010-09-08 10:05:27 -0700358static long bt_sock_data_wait(struct sock *sk, long timeo)
359{
360 DECLARE_WAITQUEUE(wait, current);
361
362 add_wait_queue(sk_sleep(sk), &wait);
363 for (;;) {
364 set_current_state(TASK_INTERRUPTIBLE);
365
366 if (!skb_queue_empty(&sk->sk_receive_queue))
367 break;
368
369 if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
370 break;
371
372 if (signal_pending(current) || !timeo)
373 break;
374
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800375 sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700376 release_sock(sk);
377 timeo = schedule_timeout(timeo);
378 lock_sock(sk);
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800379 sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
Mat Martineau796c86e2010-09-08 10:05:27 -0700380 }
381
382 __set_current_state(TASK_RUNNING);
383 remove_wait_queue(sk_sleep(sk), &wait);
384 return timeo;
385}
386
Ying Xue1b784142015-03-02 15:37:48 +0800387int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
388 size_t size, int flags)
Mat Martineau796c86e2010-09-08 10:05:27 -0700389{
390 struct sock *sk = sock->sk;
391 int err = 0;
392 size_t target, copied = 0;
393 long timeo;
394
395 if (flags & MSG_OOB)
396 return -EOPNOTSUPP;
397
Mat Martineau796c86e2010-09-08 10:05:27 -0700398 BT_DBG("sk %p size %zu", sk, size);
399
400 lock_sock(sk);
401
402 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
403 timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
404
405 do {
406 struct sk_buff *skb;
407 int chunk;
408
409 skb = skb_dequeue(&sk->sk_receive_queue);
410 if (!skb) {
411 if (copied >= target)
412 break;
413
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200414 err = sock_error(sk);
415 if (err)
Mat Martineau796c86e2010-09-08 10:05:27 -0700416 break;
417 if (sk->sk_shutdown & RCV_SHUTDOWN)
418 break;
419
420 err = -EAGAIN;
421 if (!timeo)
422 break;
423
424 timeo = bt_sock_data_wait(sk, timeo);
425
426 if (signal_pending(current)) {
427 err = sock_intr_errno(timeo);
428 goto out;
429 }
430 continue;
431 }
432
433 chunk = min_t(unsigned int, skb->len, size);
David S. Miller51f3d022014-11-05 16:46:40 -0500434 if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
Mat Martineau796c86e2010-09-08 10:05:27 -0700435 skb_queue_head(&sk->sk_receive_queue, skb);
436 if (!copied)
437 copied = -EFAULT;
438 break;
439 }
440 copied += chunk;
441 size -= chunk;
442
Erin MacNeil6fd1d512022-04-27 16:02:37 -0400443 sock_recv_cmsgs(msg, sk, skb);
Mat Martineau796c86e2010-09-08 10:05:27 -0700444
445 if (!(flags & MSG_PEEK)) {
Mat Martineau5b668eb2011-07-22 14:53:59 -0700446 int skb_len = skb_headlen(skb);
447
448 if (chunk <= skb_len) {
449 __skb_pull(skb, chunk);
450 } else {
451 struct sk_buff *frag;
452
453 __skb_pull(skb, skb_len);
454 chunk -= skb_len;
455
456 skb_walk_frags(skb, frag) {
457 if (chunk <= frag->len) {
458 /* Pulling partial data */
459 skb->len -= chunk;
460 skb->data_len -= chunk;
461 __skb_pull(frag, chunk);
462 break;
463 } else if (frag->len) {
464 /* Pulling all frag data */
465 chunk -= frag->len;
466 skb->len -= frag->len;
467 skb->data_len -= frag->len;
468 __skb_pull(frag, frag->len);
469 }
470 }
471 }
472
Mat Martineau796c86e2010-09-08 10:05:27 -0700473 if (skb->len) {
474 skb_queue_head(&sk->sk_receive_queue, skb);
475 break;
476 }
477 kfree_skb(skb);
478
479 } else {
480 /* put message back and return */
481 skb_queue_head(&sk->sk_receive_queue, skb);
482 break;
483 }
484 } while (size);
485
486out:
487 release_sock(sk);
488 return copied ? : err;
489}
490EXPORT_SYMBOL(bt_sock_stream_recvmsg);
491
Al Viroade994f2017-07-03 00:01:49 -0400492static inline __poll_t bt_accept_poll(struct sock *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
Geliang Tang7eb74042015-12-18 23:33:25 +0800494 struct bt_sock *s, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 struct sock *sk;
496
Geliang Tang7eb74042015-12-18 23:33:25 +0800497 list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
498 sk = (struct sock *)s;
Marcel Holtmannd5f2d2b2009-02-16 02:57:30 +0100499 if (sk->sk_state == BT_CONNECTED ||
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300500 (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
501 sk->sk_state == BT_CONNECT2))
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800502 return EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 }
504
505 return 0;
506}
507
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700508__poll_t bt_sock_poll(struct file *file, struct socket *sock,
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900509 poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510{
511 struct sock *sk = sock->sk;
Al Viroade994f2017-07-03 00:01:49 -0400512 __poll_t mask = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700514 poll_wait(file, sk_sleep(sk), wait);
515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 if (sk->sk_state == BT_LISTEN)
517 return bt_accept_poll(sk);
518
Eric Dumazet3ef7cf52019-10-23 22:44:50 -0700519 if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800520 mask |= EPOLLERR |
521 (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Davide Libenzif348d702006-03-25 03:07:39 -0800523 if (sk->sk_shutdown & RCV_SHUTDOWN)
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800524 mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
Davide Libenzif348d702006-03-25 03:07:39 -0800525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 if (sk->sk_shutdown == SHUTDOWN_MASK)
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800527 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Eric Dumazet3ef7cf52019-10-23 22:44:50 -0700529 if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800530 mask |= EPOLLIN | EPOLLRDNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
532 if (sk->sk_state == BT_CLOSED)
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800533 mask |= EPOLLHUP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535 if (sk->sk_state == BT_CONNECT ||
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900536 sk->sk_state == BT_CONNECT2 ||
537 sk->sk_state == BT_CONFIG)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 return mask;
539
Gustavo Padovanc5daa682012-05-16 12:17:10 -0300540 if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800541 mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 else
Eric Dumazet9cd3e072015-11-29 20:03:10 -0800543 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
545 return mask;
546}
Linus Torvaldsa11e1d42018-06-28 09:43:44 -0700547EXPORT_SYMBOL(bt_sock_poll);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200549int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
550{
551 struct sock *sk = sock->sk;
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200552 struct sk_buff *skb;
553 long amount;
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200554 int err;
555
556 BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
557
558 switch (cmd) {
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200559 case TIOCOUTQ:
560 if (sk->sk_state == BT_LISTEN)
561 return -EINVAL;
562
Eric Dumazet31e6d362009-06-17 19:05:41 -0700563 amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200564 if (amount < 0)
565 amount = 0;
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900566 err = put_user(amount, (int __user *)arg);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200567 break;
568
569 case TIOCINQ:
570 if (sk->sk_state == BT_LISTEN)
571 return -EINVAL;
572
573 lock_sock(sk);
574 skb = skb_peek(&sk->sk_receive_queue);
575 amount = skb ? skb->len : 0;
576 release_sock(sk);
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900577 err = put_user(amount, (int __user *)arg);
Marcel Holtmann43cbeee2008-07-14 20:13:51 +0200578 break;
579
Marcel Holtmann3241ad82008-07-14 20:13:50 +0200580 default:
581 err = -ENOIOCTLCMD;
582 break;
583 }
584
585 return err;
586}
587EXPORT_SYMBOL(bt_sock_ioctl);
588
Johan Hedberg0fba96f92013-09-25 13:26:04 +0300589/* This function expects the sk lock to be held when called */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
591{
592 DECLARE_WAITQUEUE(wait, current);
593 int err = 0;
594
595 BT_DBG("sk %p", sk);
596
Eric Dumazetaa395142010-04-20 13:03:51 +0000597 add_wait_queue(sk_sleep(sk), &wait);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400598 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 while (sk->sk_state != state) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 if (!timeo) {
Marcel Holtmannb4c612a2006-09-23 09:54:38 +0200601 err = -EINPROGRESS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 break;
603 }
604
605 if (signal_pending(current)) {
606 err = sock_intr_errno(timeo);
607 break;
608 }
609
610 release_sock(sk);
611 timeo = schedule_timeout(timeo);
612 lock_sock(sk);
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400613 set_current_state(TASK_INTERRUPTIBLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
Benjamin LaHaisec1cbe4b2005-12-13 23:22:19 -0800615 err = sock_error(sk);
616 if (err)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 }
Peter Hurley9be4e3f2011-07-24 00:10:46 -0400619 __set_current_state(TASK_RUNNING);
Eric Dumazetaa395142010-04-20 13:03:51 +0000620 remove_wait_queue(sk_sleep(sk), &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 return err;
622}
623EXPORT_SYMBOL(bt_sock_wait_state);
624
Johan Hedberge793dcf2013-09-16 13:05:19 +0300625/* This function expects the sk lock to be held when called */
Gavin Lida891212022-03-14 15:42:52 -0700626int bt_sock_wait_ready(struct sock *sk, unsigned int msg_flags)
Johan Hedberge793dcf2013-09-16 13:05:19 +0300627{
628 DECLARE_WAITQUEUE(wait, current);
629 unsigned long timeo;
630 int err = 0;
631
632 BT_DBG("sk %p", sk);
633
Gavin Lida891212022-03-14 15:42:52 -0700634 timeo = sock_sndtimeo(sk, !!(msg_flags & MSG_DONTWAIT));
Johan Hedberge793dcf2013-09-16 13:05:19 +0300635
636 add_wait_queue(sk_sleep(sk), &wait);
637 set_current_state(TASK_INTERRUPTIBLE);
638 while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
639 if (!timeo) {
640 err = -EAGAIN;
641 break;
642 }
643
644 if (signal_pending(current)) {
645 err = sock_intr_errno(timeo);
646 break;
647 }
648
649 release_sock(sk);
650 timeo = schedule_timeout(timeo);
651 lock_sock(sk);
652 set_current_state(TASK_INTERRUPTIBLE);
653
654 err = sock_error(sk);
655 if (err)
656 break;
657 }
658 __set_current_state(TASK_RUNNING);
659 remove_wait_queue(sk_sleep(sk), &wait);
660
661 return err;
662}
663EXPORT_SYMBOL(bt_sock_wait_ready);
664
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900665#ifdef CONFIG_PROC_FS
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900666static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
667 __acquires(seq->private->l->lock)
668{
Muchun Song359745d2022-01-21 22:14:23 -0800669 struct bt_sock_list *l = pde_data(file_inode(seq->file));
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900670
671 read_lock(&l->lock);
672 return seq_hlist_start_head(&l->head, *pos);
673}
674
675static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
676{
Muchun Song359745d2022-01-21 22:14:23 -0800677 struct bt_sock_list *l = pde_data(file_inode(seq->file));
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900678
679 return seq_hlist_next(v, &l->head, pos);
680}
681
682static void bt_seq_stop(struct seq_file *seq, void *v)
683 __releases(seq->private->l->lock)
684{
Muchun Song359745d2022-01-21 22:14:23 -0800685 struct bt_sock_list *l = pde_data(file_inode(seq->file));
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900686
687 read_unlock(&l->lock);
688}
689
690static int bt_seq_show(struct seq_file *seq, void *v)
691{
Muchun Song359745d2022-01-21 22:14:23 -0800692 struct bt_sock_list *l = pde_data(file_inode(seq->file));
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900693
694 if (v == SEQ_START_TOKEN) {
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900695 seq_puts(seq, "sk RefCnt Rmem Wmem User Inode Parent");
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900696
697 if (l->custom_seq_show) {
698 seq_putc(seq, ' ');
699 l->custom_seq_show(seq, v);
700 }
701
702 seq_putc(seq, '\n');
703 } else {
Andrei Emeltchenko09d5d4a2012-08-07 18:05:04 +0300704 struct sock *sk = sk_entry(v);
705 struct bt_sock *bt = bt_sk(sk);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900706
Andrei Emeltchenko7028a882012-09-25 12:49:45 +0300707 seq_printf(seq,
Marcel Holtmann5f6cd792013-10-13 10:34:03 -0700708 "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900709 sk,
Reshetova, Elena41c6d652017-06-30 13:08:01 +0300710 refcount_read(&sk->sk_refcnt),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900711 sk_rmem_alloc_get(sk),
712 sk_wmem_alloc_get(sk),
Eric W. Biederman1bbb3092012-10-03 20:32:17 -0700713 from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900714 sock_i_ino(sk),
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900715 bt->parent ? sock_i_ino(bt->parent) : 0LU);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900716
717 if (l->custom_seq_show) {
718 seq_putc(seq, ' ');
719 l->custom_seq_show(seq, v);
720 }
721
722 seq_putc(seq, '\n');
723 }
724 return 0;
725}
726
Fabian Frederick26b0f4e2014-06-30 19:26:23 +0200727static const struct seq_operations bt_seq_ops = {
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900728 .start = bt_seq_start,
729 .next = bt_seq_next,
730 .stop = bt_seq_stop,
731 .show = bt_seq_show,
732};
733
Al Virob0316612013-04-04 19:14:33 -0400734int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000735 struct bt_sock_list *sk_list,
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900736 int (*seq_show)(struct seq_file *, void *))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900737{
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900738 sk_list->custom_seq_show = seq_show;
739
Christoph Hellwiga9170e0a92018-04-15 10:27:22 +0200740 if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900741 return -ENOMEM;
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900742 return 0;
743}
744
745void bt_procfs_cleanup(struct net *net, const char *name)
746{
Gao fengece31ff2013-02-18 01:34:56 +0000747 remove_proc_entry(name, net->proc_net);
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900748}
749#else
Al Virob0316612013-04-04 19:14:33 -0400750int bt_procfs_init(struct net *net, const char *name,
Prasanna Karthikf37590b2015-11-17 11:06:53 +0000751 struct bt_sock_list *sk_list,
Tomoyuki Matsushitab8ddc3b2021-01-30 00:47:27 +0900752 int (*seq_show)(struct seq_file *, void *))
Masatake YAMATO256a06c2012-07-26 01:26:32 +0900753{
754 return 0;
755}
756
757void bt_procfs_cleanup(struct net *net, const char *name)
758{
759}
760#endif
761EXPORT_SYMBOL(bt_procfs_init);
762EXPORT_SYMBOL(bt_procfs_cleanup);
763
linzhang173e7832017-05-15 10:26:47 +0800764static const struct net_proto_family bt_sock_family_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 .owner = THIS_MODULE,
766 .family = PF_BLUETOOTH,
767 .create = bt_sock_create,
768};
769
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700770struct dentry *bt_debugfs;
771EXPORT_SYMBOL_GPL(bt_debugfs);
772
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200773#define VERSION __stringify(BT_SUBSYS_VERSION) "." \
774 __stringify(BT_SUBSYS_REVISION)
775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776static int __init bt_init(void)
777{
Marcel Holtmann27d35282006-07-03 10:02:37 +0200778 int err;
779
Eyal Birgerb4772ef2015-03-01 14:58:29 +0200780 sock_skb_cb_check_size(sizeof(struct bt_skb_cb));
Marcel Holtmann7cb9d202014-09-14 22:50:46 +0200781
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200782 BT_INFO("Core ver %s", VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
Marcel Holtmannee485292014-12-29 20:48:35 -0800784 err = bt_selftest();
785 if (err < 0)
786 return err;
787
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700788 bt_debugfs = debugfs_create_dir("bluetooth", NULL);
789
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200790 bt_leds_init();
791
Marcel Holtmann27d35282006-07-03 10:02:37 +0200792 err = bt_sysfs_init();
793 if (err < 0)
Chen Zhongjin2f3957c2022-11-29 17:25:56 +0800794 goto cleanup_led;
Marcel Holtmann27d35282006-07-03 10:02:37 +0200795
796 err = sock_register(&bt_sock_family_ops);
Markus Elfring1b259902017-11-08 08:03:04 +0100797 if (err)
798 goto cleanup_sysfs;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 BT_INFO("HCI device and connection manager initialized");
801
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200802 err = hci_sock_init();
Markus Elfring1b259902017-11-08 08:03:04 +0100803 if (err)
804 goto unregister_socket;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200805
806 err = l2cap_init();
Markus Elfring1b259902017-11-08 08:03:04 +0100807 if (err)
808 goto cleanup_socket;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200809
810 err = sco_init();
Markus Elfring1b259902017-11-08 08:03:04 +0100811 if (err)
812 goto cleanup_cap;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200814 err = mgmt_init();
Markus Elfring1b259902017-11-08 08:03:04 +0100815 if (err)
816 goto cleanup_sco;
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 return 0;
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200819
Markus Elfring1b259902017-11-08 08:03:04 +0100820cleanup_sco:
821 sco_exit();
822cleanup_cap:
823 l2cap_exit();
824cleanup_socket:
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200825 hci_sock_cleanup();
Markus Elfring1b259902017-11-08 08:03:04 +0100826unregister_socket:
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200827 sock_unregister(PF_BLUETOOTH);
Markus Elfring1b259902017-11-08 08:03:04 +0100828cleanup_sysfs:
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200829 bt_sysfs_cleanup();
Chen Zhongjin2f3957c2022-11-29 17:25:56 +0800830cleanup_led:
831 bt_leds_cleanup();
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200832 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833}
834
835static void __exit bt_exit(void)
836{
Johan Hedberg6d785aa32015-03-06 21:08:51 +0200837 mgmt_exit();
838
Gustavo F. Padovan64274512011-02-07 20:08:52 -0200839 sco_exit();
840
841 l2cap_exit();
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 hci_sock_cleanup();
844
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 sock_unregister(PF_BLUETOOTH);
Marcel Holtmann27d35282006-07-03 10:02:37 +0200846
847 bt_sysfs_cleanup();
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700848
Marcel Holtmanne64c97b2016-07-21 14:12:41 +0200849 bt_leds_cleanup();
850
Marcel Holtmannffcecac2013-10-17 17:24:18 -0700851 debugfs_remove_recursive(bt_debugfs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852}
853
854subsys_initcall(bt_init);
855module_exit(bt_exit);
856
Marcel Holtmann63fbd242008-08-18 13:23:53 +0200857MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
Marcel Holtmann9e8305b2016-08-30 05:00:35 +0200858MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
859MODULE_VERSION(VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860MODULE_LICENSE("GPL");
861MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);