--- zzzz-none-000/linux-3.10.107/net/bluetooth/af_bluetooth.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/net/bluetooth/af_bluetooth.c 2021-02-04 17:41:59.000000000 +0000 @@ -25,12 +25,15 @@ /* Bluetooth address family and sockets. */ #include +#include #include #include #include -#define VERSION "2.16" +#include "selftest.h" + +#define VERSION "2.21" /* Bluetooth sockets */ #define BT_MAX_PROTO 8 @@ -207,8 +210,8 @@ } EXPORT_SYMBOL(bt_accept_dequeue); -int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) +int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + int flags) { int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; @@ -218,13 +221,14 @@ BT_DBG("sock %p sk %p len %zu", sock, sk, len); - if (flags & (MSG_OOB)) + if (flags & MSG_OOB) return -EOPNOTSUPP; skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { if (sk->sk_shutdown & RCV_SHUTDOWN) return 0; + return err; } @@ -235,10 +239,15 @@ } skb_reset_transport_header(skb); - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); - if (err == 0) + err = skb_copy_datagram_msg(skb, 0, msg, copied); + if (err == 0) { sock_recv_ts_and_drops(msg, sk, skb); + if (bt_sk(sk)->skb_msg_name) + bt_sk(sk)->skb_msg_name(skb, msg->msg_name, + &msg->msg_namelen); + } + skb_free_datagram(sk, skb); return err ? : copied; @@ -262,11 +271,11 @@ if (signal_pending(current) || !timeo) break; - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); } __set_current_state(TASK_RUNNING); @@ -274,8 +283,8 @@ return timeo; } -int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size, int flags) +int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg, + size_t size, int flags) { struct sock *sk = sock->sk; int err = 0; @@ -321,7 +330,7 @@ } chunk = min_t(unsigned int, skb->len, size); - if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) { + if (skb_copy_datagram_msg(skb, 0, msg, chunk)) { skb_queue_head(&sk->sk_receive_queue, skb); if (!copied) copied = -EFAULT; @@ -432,7 +441,7 @@ if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; else - set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); + sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); return mask; } @@ -486,6 +495,7 @@ } 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); @@ -521,6 +531,46 @@ } 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 long flags) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long timeo; + int err = 0; + + BT_DBG("sk %p", sk); + + timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); + + 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 struct bt_seq_state { struct bt_sock_list *l; @@ -559,7 +609,7 @@ struct bt_sock_list *l = s->l; if (v == SEQ_START_TOKEN) { - seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Src Dst Parent"); + seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent"); if (l->custom_seq_show) { seq_putc(seq, ' '); @@ -572,15 +622,13 @@ struct bt_sock *bt = bt_sk(sk); seq_printf(seq, - "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu", + "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu", sk, atomic_read(&sk->sk_refcnt), sk_rmem_alloc_get(sk), sk_wmem_alloc_get(sk), from_kuid(seq_user_ns(seq), sock_i_uid(sk)), sock_i_ino(sk), - &bt->src, - &bt->dst, bt->parent? sock_i_ino(bt->parent): 0LU); if (l->custom_seq_show) { @@ -593,7 +641,7 @@ return 0; } -static struct seq_operations bt_seq_ops = { +static const struct seq_operations bt_seq_ops = { .start = bt_seq_start, .next = bt_seq_next, .stop = bt_seq_stop, @@ -658,12 +706,23 @@ .create = bt_sock_create, }; +struct dentry *bt_debugfs; +EXPORT_SYMBOL_GPL(bt_debugfs); + 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); + err = bt_sysfs_init(); if (err < 0) return err; @@ -690,6 +749,13 @@ goto sock_err; } + err = mgmt_init(); + if (err < 0) { + sco_exit(); + l2cap_exit(); + goto sock_err; + } + return 0; sock_err: @@ -704,6 +770,7 @@ static void __exit bt_exit(void) { + mgmt_exit(); sco_exit(); @@ -714,6 +781,8 @@ sock_unregister(PF_BLUETOOTH); bt_sysfs_cleanup(); + + debugfs_remove_recursive(bt_debugfs); } subsys_initcall(bt_init);