#include <linux/list.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/proc_fs.h>
#include <net/sock.h>
#if defined(CONFIG_KMOD)
#define BT_DBG(D...)
#endif
-#define VERSION "2.5"
-
-struct proc_dir_entry *proc_bt;
-EXPORT_SYMBOL(proc_bt);
+#define VERSION "2.8"
/* Bluetooth sockets */
-#define BT_MAX_PROTO 7
+#define BT_MAX_PROTO 8
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
-static kmem_cache_t *bt_sock_cache;
-
int bt_sock_register(int proto, struct net_proto_family *ops)
{
- if (proto >= BT_MAX_PROTO)
+ if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
if (bt_proto[proto])
int bt_sock_unregister(int proto)
{
- if (proto >= BT_MAX_PROTO)
+ if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
if (!bt_proto[proto])
{
int err = 0;
- if (proto >= BT_MAX_PROTO)
+ if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
#if defined(CONFIG_KMOD)
return err;
}
-struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio)
-{
- struct sock *sk;
- void *pi;
-
- sk = sk_alloc(PF_BLUETOOTH, prio, sizeof(struct bt_sock), bt_sock_cache);
- if (!sk)
- return NULL;
-
- if (pi_size) {
- pi = kmalloc(pi_size, prio);
- if (!pi) {
- sk_free(sk);
- return NULL;
- }
- memset(pi, 0, pi_size);
- sk->sk_protinfo = pi;
- }
-
- sock_init_data(sock, sk);
- INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
-
- sk->sk_zapped = 0;
- sk->sk_protocol = proto;
- sk->sk_state = BT_OPEN;
-
- return sk;
-}
-EXPORT_SYMBOL(bt_sock_alloc);
-
void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
{
write_lock_bh(&l->lock);
}
EXPORT_SYMBOL(bt_accept_enqueue);
-static void bt_accept_unlink(struct sock *sk)
+void bt_accept_unlink(struct sock *sk)
{
BT_DBG("sk %p state %d", sk, sk->sk_state);
bt_sk(sk)->parent = NULL;
sock_put(sk);
}
+EXPORT_SYMBOL(bt_accept_unlink);
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{
sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
lock_sock(sk);
+
+ /* FIXME: Is this check still needed */
if (sk->sk_state == BT_CLOSED) {
release_sock(sk);
bt_accept_unlink(sk);
release_sock(sk);
return sk;
}
+
release_sock(sk);
}
return NULL;
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ mask |= POLLRDHUP;
+
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
timeo = schedule_timeout(timeo);
lock_sock(sk);
- if (sk->sk_err) {
- err = sock_error(sk);
+ err = sock_error(sk);
+ if (err)
break;
- }
}
set_current_state(TASK_RUNNING);
remove_wait_queue(sk->sk_sleep, &wait);
.create = bt_sock_create,
};
-extern int hci_sock_init(void);
-extern int hci_sock_cleanup(void);
-
-extern int bt_sysfs_init(void);
-extern int bt_sysfs_cleanup(void);
-
static int __init bt_init(void)
{
BT_INFO("Core ver %s", VERSION);
- proc_bt = proc_mkdir("bluetooth", NULL);
- if (proc_bt)
- proc_bt->owner = THIS_MODULE;
-
- /* Init socket cache */
- bt_sock_cache = kmem_cache_create("bt_sock",
- sizeof(struct bt_sock), 0,
- SLAB_HWCACHE_ALIGN, 0, 0);
-
- if (!bt_sock_cache) {
- BT_ERR("Socket cache creation failed");
- return -ENOMEM;
- }
-
sock_register(&bt_sock_family_ops);
BT_INFO("HCI device and connection manager initialized");
bt_sysfs_cleanup();
sock_unregister(PF_BLUETOOTH);
- kmem_cache_destroy(bt_sock_cache);
-
- remove_proc_entry("bluetooth", NULL);
}
subsys_initcall(bt_init);