#include <linux/poll.h>
#include <net/sock.h>
#include <asm/ioctls.h>
-
-#if defined(CONFIG_KMOD)
#include <linux/kmod.h>
-#endif
#include <net/bluetooth/bluetooth.h>
-#ifndef CONFIG_BT_SOCK_DEBUG
-#undef BT_DBG
-#define BT_DBG(D...)
-#endif
-
-#define VERSION "2.11"
+#define VERSION "2.15"
/* Bluetooth sockets */
#define BT_MAX_PROTO 8
-static struct net_proto_family *bt_proto[BT_MAX_PROTO];
+static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
+static DEFINE_RWLOCK(bt_proto_lock);
-static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
-static const char *bt_key_strings[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_AVDTP",
};
-static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
+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_HIDP",
"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
};
-static DEFINE_RWLOCK(bt_proto_lock);
-int bt_sock_register(int proto, struct net_proto_family *ops)
+static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+{
+ struct sock *sk = sock->sk;
+
+ if (!sk)
+ return;
+
+ BUG_ON(sock_owned_by_user(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]);
+}
+
+int bt_sock_register(int proto, const struct net_proto_family *ops)
{
int err = 0;
}
EXPORT_SYMBOL(bt_sock_unregister);
-static void bt_reclassify_sock_lock(struct socket *sock, int proto)
-{
- struct sock *sk = sock->sk;
-
- if (!sk)
- return;
- BUG_ON(sock_owned_by_user(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]);
-}
-
-static int bt_sock_create(struct net *net, struct socket *sock, int proto)
+static int bt_sock_create(struct net *net, struct socket *sock, int proto,
+ int kern)
{
int err;
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
-#if defined(CONFIG_KMOD)
- if (!bt_proto[proto]) {
+ if (!bt_proto[proto])
request_module("bt-proto-%d", proto);
- }
-#endif
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);
- bt_reclassify_sock_lock(sock, proto);
+ err = bt_proto[proto]->create(net, sock, proto, kern);
+ bt_sock_reclassify_lock(sock, proto);
module_put(bt_proto[proto]->owner);
}
continue;
}
- if (sk->sk_state == BT_CONNECTED || !newsock) {
+ if (sk->sk_state == BT_CONNECTED || !newsock ||
+ bt_sk(parent)->defer_setup) {
bt_accept_unlink(sk);
if (newsock)
sock_graft(sk, newsock);
EXPORT_SYMBOL(bt_accept_dequeue);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t len, int flags)
+ struct msghdr *msg, size_t len, int flags)
{
int noblock = flags & MSG_DONTWAIT;
struct sock *sk = sock->sk;
size_t copied;
int err;
- BT_DBG("sock %p sk %p len %d", sock, sk, len);
+ BT_DBG("sock %p sk %p len %zu", sock, sk, len);
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
skb_reset_transport_header(skb);
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (err == 0)
- sock_recv_timestamp(msg, sk, skb);
+ sock_recv_ts_and_drops(msg, sk, skb);
skb_free_datagram(sk, skb);
list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
- if (sk->sk_state == BT_CONNECTED)
+ if (sk->sk_state == BT_CONNECTED ||
+ (bt_sk(parent)->defer_setup &&
+ sk->sk_state == BT_CONNECT2))
return POLLIN | POLLRDNORM;
}
if (sk->sk_state == BT_LISTEN)
return -EINVAL;
- amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
+ amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0)
amount = 0;
err = put_user(amount, (int __user *) arg);
subsys_initcall(bt_init);
module_exit(bt_exit);
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");