// SPDX-License-Identifier: GPL-2.0
/*
   BlueZ - Bluetooth protocol stack for Linux
   Copyright (C) 2000-2001 Qualcomm Incorporated

   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
   SOFTWARE IS DISCLAIMED.
*/

/* Bluetooth address family and sockets. */

#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/stringify.h>
#include <linux/sched/signal.h>

#include <asm/ioctls.h>

#include <net/bluetooth/bluetooth.h>
#include <linux/proc_fs.h>

#include <linux/ethtool.h>
#include <linux/sockios.h>

#include "leds.h"
#include "selftest.h"

/* Bluetooth sockets */
#define BT_MAX_PROTO	(BTPROTO_LAST + 1)
static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
static DEFINE_RWLOCK(bt_proto_lock);

static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
static const char *const bt_key_strings[BT_MAX_PROTO] = {
	"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
	"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
	"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
	"sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
	"sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
	"sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
	"sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
	"sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
	"sk_lock-AF_BLUETOOTH-BTPROTO_ISO",
};

static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
	"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
	"slock-AF_BLUETOOTH-BTPROTO_HCI",
	"slock-AF_BLUETOOTH-BTPROTO_SCO",
	"slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
	"slock-AF_BLUETOOTH-BTPROTO_BNEP",
	"slock-AF_BLUETOOTH-BTPROTO_CMTP",
	"slock-AF_BLUETOOTH-BTPROTO_HIDP",
	"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
	"slock-AF_BLUETOOTH-BTPROTO_ISO",
};

void bt_sock_reclassify_lock(struct sock *sk, int proto)
{
	BUG_ON(!sk);
	BUG_ON(!sock_allow_reclassification(sk));

	sock_lock_init_class_and_name(sk,
				      bt_slock_key_strings[proto], &bt_slock_key[proto],
				      bt_key_strings[proto], &bt_lock_key[proto]);
}
EXPORT_SYMBOL(bt_sock_reclassify_lock);

int bt_sock_register(int proto, const struct net_proto_family *ops)
{
	int err = 0;

	if (proto < 0 || proto >= BT_MAX_PROTO)
		return -EINVAL;

	write_lock(&bt_proto_lock);

	if (bt_proto[proto])
		err = -EEXIST;
	else
		bt_proto[proto] = ops;

	write_unlock(&bt_proto_lock);

	return err;
}
EXPORT_SYMBOL(bt_sock_register);

void bt_sock_unregister(int proto)
{
	if (proto < 0 || proto >= BT_MAX_PROTO)
		return;

	write_lock(&bt_proto_lock);
	bt_proto[proto] = NULL;
	write_unlock(&bt_proto_lock);
}
EXPORT_SYMBOL(bt_sock_unregister);

static int bt_sock_create(struct net *net, struct socket *sock, int proto,
			  int kern)
{
	int err;

	if (net != &init_net)
		return -EAFNOSUPPORT;

	if (proto < 0 || proto >= BT_MAX_PROTO)
		return -EINVAL;

	if (!bt_proto[proto])
		request_module("bt-proto-%d", proto);

	err = -EPROTONOSUPPORT;

	read_lock(&bt_proto_lock);

	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
		err = bt_proto[proto]->create(net, sock, proto, kern);
		if (!err)
			bt_sock_reclassify_lock(sock->sk, proto);
		module_put(bt_proto[proto]->owner);
	}

	read_unlock(&bt_proto_lock);

	return err;
}

struct sock *bt_sock_alloc(struct net *net, struct socket *sock,
			   struct proto *prot, int proto, gfp_t prio, int kern)
{
	struct sock *sk;

	sk = sk_alloc(net, PF_BLUETOOTH, prio, prot, kern);
	if (!sk)
		return NULL;

	sock_init_data(sock, sk);
	INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
	spin_lock_init(&bt_sk(sk)->accept_q_lock);

	sock_reset_flag(sk, SOCK_ZAPPED);

	sk->sk_protocol = proto;
	sk->sk_state    = BT_OPEN;

	/* Init peer information so it can be properly monitored */
	if (!kern) {
		spin_lock(&sk->sk_peer_lock);
		sk->sk_peer_pid  = get_pid(task_tgid(current));
		sk->sk_peer_cred = get_current_cred();
		spin_unlock(&sk->sk_peer_lock);
	}

	return sk;
}
EXPORT_SYMBOL(bt_sock_alloc);

void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
{
	write_lock(&l->lock);
	sk_add_node(sk, &l->head);
	write_unlock(&l->lock);
}
EXPORT_SYMBOL(bt_sock_link);

void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
{
	write_lock(&l->lock);
	sk_del_node_init(sk);
	write_unlock(&l->lock);
}
EXPORT_SYMBOL(bt_sock_unlink);

bool bt_sock_linked(struct bt_sock_list *l, struct sock *s)
{
	struct sock *sk;

	if (!l || !s)
		return false;

	read_lock(&l->lock);

	sk_for_each(sk, &l->head) {
		if (s == sk) {
			read_unlock(&l->lock);
			return true;
		}
	}

	read_unlock(&l->lock);

	return false;
}
EXPORT_SYMBOL(bt_sock_linked);

void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
	__context_unsafe(/* conditional locking */)
{
	const struct cred *old_cred;
	struct pid *old_pid;
	struct bt_sock *par = bt_sk(parent);

	BT_DBG("parent %p, sk %p", parent, sk);

	sock_hold(sk);

	if (bh)
		bh_lock_sock_nested(sk);
	else
		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);

	bt_sk(sk)->parent = parent;

	spin_lock_bh(&par->accept_q_lock);
	list_add_tail(&bt_sk(sk)->accept_q, &par->accept_q);
	sk_acceptq_added(parent);
	spin_unlock_bh(&par->accept_q_lock);

	/* Copy credentials from parent since for incoming connections the
	 * socket is allocated by the kernel.
	 */
	spin_lock(&sk->sk_peer_lock);
	old_pid = sk->sk_peer_pid;
	old_cred = sk->sk_peer_cred;
	sk->sk_peer_pid = get_pid(parent->sk_peer_pid);
	sk->sk_peer_cred = get_cred(parent->sk_peer_cred);
	spin_unlock(&sk->sk_peer_lock);

	put_pid(old_pid);
	put_cred(old_cred);

	if (bh)
		bh_unlock_sock(sk);
	else
		release_sock(sk);
}
EXPORT_SYMBOL(bt_accept_enqueue);

/* Calling function must hold the sk lock.
 * bt_sk(sk)->parent must be non-NULL meaning sk is in the parent list.
 */
void bt_accept_unlink(struct sock *sk)
{
	struct sock *parent = bt_sk(sk)->parent;

	BT_DBG("sk %p state %d", sk, sk->sk_state);

	spin_lock_bh(&bt_sk(parent)->accept_q_lock);
	list_del_init(&bt_sk(sk)->accept_q);
	sk_acceptq_removed(parent);
	spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
	bt_sk(sk)->parent = NULL;
	sock_put(sk);
}
EXPORT_SYMBOL(bt_accept_unlink);

static struct sock *bt_accept_get(struct sock *parent, struct sock *sk)
{
	struct bt_sock *bt = bt_sk(parent);
	struct sock *next = NULL;

	/* accept_q is modified from child teardown paths too, so take a
	 * temporary reference before dropping the queue lock.
	 */
	spin_lock_bh(&bt->accept_q_lock);

	if (sk) {
		if (bt_sk(sk)->parent != parent)
			goto out;

		if (!list_is_last(&bt_sk(sk)->accept_q, &bt->accept_q)) {
			next = &list_next_entry(bt_sk(sk), accept_q)->sk;
			sock_hold(next);
		}
	} else if (!list_empty(&bt->accept_q)) {
		next = &list_first_entry(&bt->accept_q,
					 struct bt_sock, accept_q)->sk;
		sock_hold(next);
	}

out:
	spin_unlock_bh(&bt->accept_q_lock);
	return next;
}

struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{
	struct sock *sk, *next;

	BT_DBG("parent %p", parent);

restart:
	for (sk = bt_accept_get(parent, NULL); sk; sk = next) {
		/* The reference from bt_accept_get() keeps sk alive. */
		lock_sock(sk);

		/* Check sk has not already been unlinked via
		 * bt_accept_unlink() due to serialisation caused by sk locking
		 */
		if (bt_sk(sk)->parent != parent) {
			BT_DBG("sk %p, already unlinked", sk);
			release_sock(sk);
			sock_put(sk);

			goto restart;
		}

		next = bt_accept_get(parent, sk);

		/* FIXME: Is this check still needed */
		if (sk->sk_state == BT_CLOSED) {
			bt_accept_unlink(sk);
			release_sock(sk);
			sock_put(sk);
			continue;
		}

		if (sk->sk_state == BT_CONNECTED || !newsock ||
		    test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
			bt_accept_unlink(sk);
			if (newsock)
				sock_graft(sk, newsock);

			release_sock(sk);
			if (next)
				sock_put(next);
			return sk;
		}

		release_sock(sk);
		sock_put(sk);
	}

	return NULL;
}
EXPORT_SYMBOL(bt_accept_dequeue);

int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
		    int flags)
{
	struct sock *sk = sock->sk;
	struct sk_buff *skb;
	size_t copied;
	size_t skblen;
	int err;

	BT_DBG("sock %p sk %p len %zu", sock, sk, len);

	if (flags & MSG_OOB)
		return -EOPNOTSUPP;

	skb = skb_recv_datagram(sk, flags, &err);
	if (!skb) {
		if (sk->sk_shutdown & RCV_SHUTDOWN)
			err = 0;

		return err;
	}

	skblen = skb->len;
	copied = skb->len;
	if (len < copied) {
		msg->msg_flags |= MSG_TRUNC;
		copied = len;
	}

	skb_reset_transport_header(skb);
	err = skb_copy_datagram_msg(skb, 0, msg, copied);
	if (err == 0) {
		sock_recv_cmsgs(msg, sk, skb);

		if (msg->msg_name && bt_sk(sk)->skb_msg_name)
			bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
						&msg->msg_namelen);

		if (test_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags)) {
			u8 pkt_status = hci_skb_pkt_status(skb);

			put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_STATUS,
				 sizeof(pkt_status), &pkt_status);
		}

		if (test_bit(BT_SK_PKT_SEQNUM, &bt_sk(sk)->flags)) {
			u16 pkt_seqnum = hci_skb_pkt_seqnum(skb);

			put_cmsg(msg, SOL_BLUETOOTH, BT_SCM_PKT_SEQNUM,
				 sizeof(pkt_seqnum), &pkt_seqnum);
		}
	}

	skb_free_datagram(sk, skb);

	if (flags & MSG_TRUNC)
		copied = skblen;

	return err ? : copied;
}
EXPORT_SYMBOL(bt_sock_recvmsg);

static long bt_sock_data_wait(struct sock *sk, long timeo)
{
	DECLARE_WAITQUEUE(wait, current);

	add_wait_queue(sk_sleep(sk), &wait);
	for (;;) {
		set_current_state(TASK_INTERRUPTIBLE);

		if (!skb_queue_empty(&sk->sk_receive_queue))
			break;

		if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
			break;

		if (signal_pending(current) || !timeo)
			break;

		sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
	}

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_sleep(sk), &wait);
	return timeo;
}

int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
			   size_t size, int flags)
{
	struct sock *sk = sock->sk;
	int err = 0;
	size_t target, copied = 0;
	long timeo;

	if (flags & MSG_OOB)
		return -EOPNOTSUPP;

	BT_DBG("sk %p size %zu", sk, size);

	lock_sock(sk);

	target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
	timeo  = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);

	do {
		struct sk_buff *skb;
		int chunk;

		skb = skb_dequeue(&sk->sk_receive_queue);
		if (!skb) {
			if (copied >= target)
				break;

			err = sock_error(sk);
			if (err)
				break;
			if (sk->sk_shutdown & RCV_SHUTDOWN)
				break;

			err = -EAGAIN;
			if (!timeo)
				break;

			timeo = bt_sock_data_wait(sk, timeo);

			if (signal_pending(current)) {
				err = sock_intr_errno(timeo);
				goto out;
			}
			continue;
		}

		chunk = min_t(unsigned int, skb->len, size);
		if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
			skb_queue_head(&sk->sk_receive_queue, skb);
			if (!copied)
				copied = -EFAULT;
			break;
		}
		copied += chunk;
		size   -= chunk;

		sock_recv_cmsgs(msg, sk, skb);

		if (!(flags & MSG_PEEK)) {
			int skb_len = skb_headlen(skb);

			if (chunk <= skb_len) {
				__skb_pull(skb, chunk);
			} else {
				struct sk_buff *frag;

				__skb_pull(skb, skb_len);
				chunk -= skb_len;

				skb_walk_frags(skb, frag) {
					if (chunk <= frag->len) {
						/* Pulling partial data */
						skb->len -= chunk;
						skb->data_len -= chunk;
						__skb_pull(frag, chunk);
						break;
					} else if (frag->len) {
						/* Pulling all frag data */
						chunk -= frag->len;
						skb->len -= frag->len;
						skb->data_len -= frag->len;
						__skb_pull(frag, frag->len);
					}
				}
			}

			if (skb->len) {
				skb_queue_head(&sk->sk_receive_queue, skb);
				break;
			}
			kfree_skb(skb);

		} else {
			/* put message back and return */
			skb_queue_head(&sk->sk_receive_queue, skb);
			break;
		}
	} while (size);

out:
	release_sock(sk);
	return copied ? : err;
}
EXPORT_SYMBOL(bt_sock_stream_recvmsg);

static inline __poll_t bt_accept_poll(struct sock *parent)
{
	struct bt_sock *bt = bt_sk(parent);
	struct bt_sock *s;
	struct sock *sk;
	__poll_t mask = 0;

	spin_lock_bh(&bt->accept_q_lock);
	list_for_each_entry(s, &bt->accept_q, accept_q) {
		int state;

		sk = (struct sock *)s;
		state = READ_ONCE(sk->sk_state);

		if (state == BT_CONNECTED ||
		    (test_bit(BT_SK_DEFER_SETUP, &bt->flags) &&
		     state == BT_CONNECT2)) {
			mask = EPOLLIN | EPOLLRDNORM;
			break;
		}
	}
	spin_unlock_bh(&bt->accept_q_lock);

	return mask;
}

__poll_t bt_sock_poll(struct file *file, struct socket *sock,
		      poll_table *wait)
{
	struct sock *sk = sock->sk;
	__poll_t mask = 0;

	poll_wait(file, sk_sleep(sk), wait);

	if (sk->sk_state == BT_LISTEN)
		return bt_accept_poll(sk);

	if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
		mask |= EPOLLERR |
			(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);

	if (sk->sk_shutdown & RCV_SHUTDOWN)
		mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;

	if (sk->sk_shutdown == SHUTDOWN_MASK)
		mask |= EPOLLHUP;

	if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
		mask |= EPOLLIN | EPOLLRDNORM;

	if (sk->sk_state == BT_CLOSED)
		mask |= EPOLLHUP;

	if (sk->sk_state == BT_CONNECT ||
	    sk->sk_state == BT_CONNECT2 ||
	    sk->sk_state == BT_CONFIG)
		return mask;

	if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
		mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
	else
		sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);

	return mask;
}
EXPORT_SYMBOL(bt_sock_poll);

static int bt_ethtool_get_ts_info(struct sock *sk, unsigned int index,
				  void __user *useraddr)
{
	struct ethtool_ts_info info;
	struct kernel_ethtool_ts_info ts_info = {};
	int ret;

	ret = hci_ethtool_ts_info(index, sk->sk_protocol, &ts_info);
	if (ret == -ENODEV)
		return ret;
	else if (ret < 0)
		return -EIO;

	memset(&info, 0, sizeof(info));

	info.cmd = ETHTOOL_GET_TS_INFO;
	info.so_timestamping = ts_info.so_timestamping;
	info.phc_index = ts_info.phc_index;
	info.tx_types = ts_info.tx_types;
	info.rx_filters = ts_info.rx_filters;

	if (copy_to_user(useraddr, &info, sizeof(info)))
		return -EFAULT;

	return 0;
}

static int bt_ethtool(struct sock *sk, const struct ifreq *ifr,
		      void __user *useraddr)
{
	unsigned int index;
	u32 ethcmd;
	int n;

	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
		return -EFAULT;

	if (sscanf(ifr->ifr_name, "hci%u%n", &index, &n) != 1 ||
	    n != strlen(ifr->ifr_name))
		return -ENODEV;

	switch (ethcmd) {
	case ETHTOOL_GET_TS_INFO:
		return bt_ethtool_get_ts_info(sk, index, useraddr);
	}

	return -EOPNOTSUPP;
}

static int bt_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
{
	struct sock *sk = sock->sk;
	struct ifreq ifr = {};
	void __user *data;
	char *colon;
	int ret = -ENOIOCTLCMD;

	if (get_user_ifreq(&ifr, &data, arg))
		return -EFAULT;

	ifr.ifr_name[IFNAMSIZ - 1] = 0;
	colon = strchr(ifr.ifr_name, ':');
	if (colon)
		*colon = 0;

	switch (cmd) {
	case SIOCETHTOOL:
		ret = bt_ethtool(sk, &ifr, data);
		break;
	}

	if (colon)
		*colon = ':';

	if (put_user_ifreq(&ifr, arg))
		return -EFAULT;

	return ret;
}

int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	struct sock *sk = sock->sk;
	struct sk_buff *skb;
	long amount;
	int err;

	BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);

	switch (cmd) {
	case TIOCOUTQ:
		if (sk->sk_state == BT_LISTEN)
			return -EINVAL;

		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
		if (amount < 0)
			amount = 0;
		err = put_user(amount, (int __user *)arg);
		break;

	case TIOCINQ:
		if (sk->sk_state == BT_LISTEN)
			return -EINVAL;

		spin_lock(&sk->sk_receive_queue.lock);
		skb = skb_peek(&sk->sk_receive_queue);
		amount = skb ? skb->len : 0;
		spin_unlock(&sk->sk_receive_queue.lock);

		err = put_user(amount, (int __user *)arg);
		break;

	case SIOCETHTOOL:
		err = bt_dev_ioctl(sock, cmd, (void __user *)arg);
		break;

	default:
		err = -ENOIOCTLCMD;
		break;
	}

	return err;
}
EXPORT_SYMBOL(bt_sock_ioctl);

/* This function expects the sk lock to be held when called */
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
{
	DECLARE_WAITQUEUE(wait, current);
	int err = 0;

	BT_DBG("sk %p", sk);

	add_wait_queue(sk_sleep(sk), &wait);
	set_current_state(TASK_INTERRUPTIBLE);
	while (sk->sk_state != state) {
		if (!timeo) {
			err = -EINPROGRESS;
			break;
		}

		if (signal_pending(current)) {
			err = sock_intr_errno(timeo);
			break;
		}

		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		set_current_state(TASK_INTERRUPTIBLE);

		err = sock_error(sk);
		if (err)
			break;
	}
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_sleep(sk), &wait);
	return err;
}
EXPORT_SYMBOL(bt_sock_wait_state);

/* This function expects the sk lock to be held when called */
int bt_sock_wait_ready(struct sock *sk, unsigned int msg_flags)
{
	DECLARE_WAITQUEUE(wait, current);
	unsigned long timeo;
	int err = 0;

	BT_DBG("sk %p", sk);

	timeo = sock_sndtimeo(sk, !!(msg_flags & MSG_DONTWAIT));

	add_wait_queue(sk_sleep(sk), &wait);
	set_current_state(TASK_INTERRUPTIBLE);
	while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
		if (!timeo) {
			err = -EAGAIN;
			break;
		}

		if (signal_pending(current)) {
			err = sock_intr_errno(timeo);
			break;
		}

		release_sock(sk);
		timeo = schedule_timeout(timeo);
		lock_sock(sk);
		set_current_state(TASK_INTERRUPTIBLE);

		err = sock_error(sk);
		if (err)
			break;
	}
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_sleep(sk), &wait);

	return err;
}
EXPORT_SYMBOL(bt_sock_wait_ready);

#ifdef CONFIG_PROC_FS
static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
	__acquires_shared(&((struct bt_sock_list *)
			    pde_data(file_inode(seq->file)))->lock)
{
	struct bt_sock_list *l = pde_data(file_inode(seq->file));

	read_lock(&l->lock);
	return seq_hlist_start_head(&l->head, *pos);
}

static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct bt_sock_list *l = pde_data(file_inode(seq->file));

	return seq_hlist_next(v, &l->head, pos);
}

static void bt_seq_stop(struct seq_file *seq, void *v)
	__releases_shared(&((struct bt_sock_list *)
			    pde_data(file_inode(seq->file)))->lock)
{
	struct bt_sock_list *l = pde_data(file_inode(seq->file));

	read_unlock(&l->lock);
}

static int bt_seq_show(struct seq_file *seq, void *v)
{
	struct bt_sock_list *l = pde_data(file_inode(seq->file));

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "sk               RefCnt Rmem   Wmem   User   Inode  Parent");

		if (l->custom_seq_show) {
			seq_putc(seq, ' ');
			l->custom_seq_show(seq, v);
		}

		seq_putc(seq, '\n');
	} else {
		struct sock *sk = sk_entry(v);
		struct bt_sock *bt = bt_sk(sk);

		seq_printf(seq,
			   "%pK %-6d %-6u %-6u %-6u %-6llu %-6llu",
			   sk,
			   refcount_read(&sk->sk_refcnt),
			   sk_rmem_alloc_get(sk),
			   sk_wmem_alloc_get(sk),
			   from_kuid(seq_user_ns(seq), sk_uid(sk)),
			   sock_i_ino(sk),
			   bt->parent ? sock_i_ino(bt->parent) : 0ULL);

		if (l->custom_seq_show) {
			seq_putc(seq, ' ');
			l->custom_seq_show(seq, v);
		}

		seq_putc(seq, '\n');
	}
	return 0;
}

static const struct seq_operations bt_seq_ops = {
	.start = bt_seq_start,
	.next  = bt_seq_next,
	.stop  = bt_seq_stop,
	.show  = bt_seq_show,
};

int bt_procfs_init(struct net *net, const char *name,
		   struct bt_sock_list *sk_list,
		   int (*seq_show)(struct seq_file *, void *))
{
	sk_list->custom_seq_show = seq_show;

	if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list))
		return -ENOMEM;
	return 0;
}

void bt_procfs_cleanup(struct net *net, const char *name)
{
	remove_proc_entry(name, net->proc_net);
}
#else
int bt_procfs_init(struct net *net, const char *name,
		   struct bt_sock_list *sk_list,
		   int (*seq_show)(struct seq_file *, void *))
{
	return 0;
}

void bt_procfs_cleanup(struct net *net, const char *name)
{
}
#endif
EXPORT_SYMBOL(bt_procfs_init);
EXPORT_SYMBOL(bt_procfs_cleanup);

static const struct net_proto_family bt_sock_family_ops = {
	.owner	= THIS_MODULE,
	.family	= PF_BLUETOOTH,
	.create	= bt_sock_create,
};

struct dentry *bt_debugfs;
EXPORT_SYMBOL_GPL(bt_debugfs);

#define VERSION __stringify(BT_SUBSYS_VERSION) "." \
		__stringify(BT_SUBSYS_REVISION)

static int __init bt_init(void)
{
	int err;

	sock_skb_cb_check_size(sizeof(struct bt_skb_cb));

	BT_INFO("Core ver %s", VERSION);

	err = bt_selftest();
	if (err < 0)
		return err;

	bt_debugfs = debugfs_create_dir("bluetooth", NULL);

	bt_leds_init();

	err = bt_sysfs_init();
	if (err < 0)
		goto cleanup_led;

	err = sock_register(&bt_sock_family_ops);
	if (err)
		goto cleanup_sysfs;

	BT_INFO("HCI device and connection manager initialized");

	err = hci_sock_init();
	if (err)
		goto unregister_socket;

	err = l2cap_init();
	if (err)
		goto cleanup_socket;

	err = sco_init();
	if (err)
		goto cleanup_cap;

	err = mgmt_init();
	if (err)
		goto cleanup_sco;

	return 0;

cleanup_sco:
	sco_exit();
cleanup_cap:
	l2cap_exit();
cleanup_socket:
	hci_sock_cleanup();
unregister_socket:
	sock_unregister(PF_BLUETOOTH);
cleanup_sysfs:
	bt_sysfs_cleanup();
cleanup_led:
	bt_leds_cleanup();
	debugfs_remove_recursive(bt_debugfs);
	return err;
}

static void __exit bt_exit(void)
{
	iso_exit();

	mgmt_exit();

	sco_exit();

	l2cap_exit();

	hci_sock_cleanup();

	sock_unregister(PF_BLUETOOTH);

	bt_sysfs_cleanup();

	bt_leds_cleanup();

	debugfs_remove_recursive(bt_debugfs);
}

subsys_initcall(bt_init);
module_exit(bt_exit);

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
