X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbluetooth%2Fl2cap.c;h=f6b4a8085357a6c0973872665272118516f72816;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ff8d31015211dc3ca01e427f89c29888f48786e2;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index ff8d31015..f6b4a8085 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -28,9 +28,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -39,9 +39,8 @@ #include #include #include -#include -#include #include +#include #include #include @@ -57,9 +56,9 @@ #define BT_DBG(D...) #endif -#define VERSION "2.7" +#define VERSION "2.8" -static struct proto_ops l2cap_sock_ops; +static const struct proto_ops l2cap_sock_ops; static struct bt_sock_list l2cap_sk_list = { .lock = RW_LOCK_UNLOCKED @@ -264,9 +263,6 @@ static void l2cap_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); - - if (sk->sk_protinfo) - kfree(sk->sk_protinfo); } static void l2cap_sock_cleanup_listen(struct sock *parent) @@ -280,7 +276,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) l2cap_sock_close(sk); parent->sk_state = BT_CLOSED; - parent->sk_zapped = 1; + sock_set_flag(parent, SOCK_ZAPPED); } /* Kill socket (only if zapped and orphan) @@ -288,7 +284,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) */ static void l2cap_sock_kill(struct sock *sk) { - if (!sk->sk_zapped || sk->sk_socket) + if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; BT_DBG("sk %p state %d", sk, sk->sk_state); @@ -333,7 +329,7 @@ static void __l2cap_sock_close(struct sock *sk, int reason) break; default: - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); break; } } @@ -370,19 +366,28 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent) pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; } -static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio) +static struct proto l2cap_proto = { + .name = "L2CAP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct l2cap_pinfo) +}; + +static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio) { struct sock *sk; - sk = bt_sock_alloc(sock, proto, sizeof(struct l2cap_pinfo), prio); + sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1); if (!sk) return NULL; - sk_set_owner(sk, THIS_MODULE); + sock_init_data(sock, sk); + INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_destruct = l2cap_sock_destruct; sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; + sock_reset_flag(sk, SOCK_ZAPPED); + sk->sk_protocol = proto; sk->sk_state = BT_OPEN; @@ -763,8 +768,9 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms BT_DBG("sock %p, sk %p", sock, sk); - if (sk->sk_err) - return sock_error(sk); + err = sock_error(sk); + if (err) + return err; if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; @@ -1062,7 +1068,7 @@ static void l2cap_chan_del(struct sock *sk, int err) } sk->sk_state = BT_CLOSED; - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); if (err) sk->sk_err = err; @@ -1410,7 +1416,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd result = L2CAP_CR_NO_MEM; /* Check for backlog size */ - if (parent->sk_ack_backlog > parent->sk_max_ack_backlog) { + if (sk_acceptq_is_full(parent)) { BT_DBG("backlog full %d", parent->sk_ack_backlog); goto response; } @@ -1424,7 +1430,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd /* Check if we already have channel with that dcid */ if (__l2cap_get_chan_by_dcid(list, scid)) { write_unlock(&list->lock); - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); l2cap_sock_kill(sk); goto response; } @@ -2132,96 +2138,31 @@ drop: return 0; } -/* ---- Proc fs support ---- */ -#ifdef CONFIG_PROC_FS -static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos) +static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) { struct sock *sk; struct hlist_node *node; - loff_t l = *pos; + char *str = buf; read_lock_bh(&l2cap_sk_list.lock); - sk_for_each(sk, node, &l2cap_sk_list.head) - if (!l--) - goto found; - sk = NULL; -found: - return sk; -} + sk_for_each(sk, node, &l2cap_sk_list.head) { + struct l2cap_pinfo *pi = l2cap_pi(sk); -static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos) -{ - (*pos)++; - return sk_next(e); -} + str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, + pi->omtu, pi->link_mode); + } -static void l2cap_seq_stop(struct seq_file *seq, void *e) -{ read_unlock_bh(&l2cap_sk_list.lock); -} - -static int l2cap_seq_show(struct seq_file *seq, void *e) -{ - struct sock *sk = e; - struct l2cap_pinfo *pi = l2cap_pi(sk); - seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, - pi->omtu, pi->link_mode); - return 0; + return (str - buf); } -static struct seq_operations l2cap_seq_ops = { - .start = l2cap_seq_start, - .next = l2cap_seq_next, - .stop = l2cap_seq_stop, - .show = l2cap_seq_show -}; - -static int l2cap_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &l2cap_seq_ops); -} +static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); -static struct file_operations l2cap_seq_fops = { - .owner = THIS_MODULE, - .open = l2cap_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int __init l2cap_proc_init(void) -{ - struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt); - if (!p) - return -ENOMEM; - p->owner = THIS_MODULE; - p->proc_fops = &l2cap_seq_fops; - return 0; -} - -static void __exit l2cap_proc_cleanup(void) -{ - remove_proc_entry("l2cap", proc_bt); -} - -#else /* CONFIG_PROC_FS */ - -static int __init l2cap_proc_init(void) -{ - return 0; -} - -static void __exit l2cap_proc_cleanup(void) -{ - return; -} -#endif /* CONFIG_PROC_FS */ - -static struct proto_ops l2cap_sock_ops = { +static const struct proto_ops l2cap_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, .release = l2cap_sock_release, @@ -2262,34 +2203,46 @@ static int __init l2cap_init(void) { int err; - if ((err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) { - BT_ERR("L2CAP socket registration failed"); + err = proto_register(&l2cap_proto, 0); + if (err < 0) return err; + + err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); + if (err < 0) { + BT_ERR("L2CAP socket registration failed"); + goto error; } - if ((err = hci_register_proto(&l2cap_hci_proto))) { + err = hci_register_proto(&l2cap_hci_proto); + if (err < 0) { BT_ERR("L2CAP protocol registration failed"); - return err; + bt_sock_unregister(BTPROTO_L2CAP); + goto error; } - l2cap_proc_init(); + class_create_file(&bt_class, &class_attr_l2cap); BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP socket layer initialized"); return 0; + +error: + proto_unregister(&l2cap_proto); + return err; } static void __exit l2cap_exit(void) { - l2cap_proc_cleanup(); + class_remove_file(&bt_class, &class_attr_l2cap); - /* Unregister socket and protocol */ - if (bt_sock_unregister(BTPROTO_L2CAP)) + if (bt_sock_unregister(BTPROTO_L2CAP) < 0) BT_ERR("L2CAP socket unregistration failed"); - if (hci_unregister_proto(&l2cap_hci_proto)) + if (hci_unregister_proto(&l2cap_hci_proto) < 0) BT_ERR("L2CAP protocol unregistration failed"); + + proto_unregister(&l2cap_proto); } void l2cap_load(void)