X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbluetooth%2Fsco.c;h=6b61323ce23cad772371657cf18833027f56d0f9;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=ac01c408238e592f58943fc2601ab45e9d732120;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index ac01c4082..6b61323ce 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -39,8 +38,7 @@ #include #include #include -#include -#include +#include #include #include @@ -56,9 +54,9 @@ #define BT_DBG(D...) #endif -#define VERSION "0.4" +#define VERSION "0.5" -static struct proto_ops sco_sock_ops; +static const struct proto_ops sco_sock_ops; static struct bt_sock_list sco_sk_list = { .lock = RW_LOCK_UNLOCKED @@ -334,9 +332,6 @@ static void sco_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 sco_sock_cleanup_listen(struct sock *parent) @@ -352,7 +347,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) } parent->sk_state = BT_CLOSED; - parent->sk_zapped = 1; + sock_set_flag(parent, SOCK_ZAPPED); } /* Kill socket (only if zapped and orphan) @@ -360,7 +355,7 @@ static void sco_sock_cleanup_listen(struct sock *parent) */ static void sco_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); @@ -399,7 +394,7 @@ static void sco_sock_close(struct sock *sk) break; default: - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); break; }; @@ -416,18 +411,29 @@ static void sco_sock_init(struct sock *sk, struct sock *parent) sk->sk_type = parent->sk_type; } -static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio) +static struct proto sco_proto = { + .name = "SCO", + .owner = THIS_MODULE, + .obj_size = sizeof(struct sco_pinfo) +}; + +static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio) { struct sock *sk; - sk = bt_sock_alloc(sock, proto, sizeof(struct sco_pinfo), prio); + sk = sk_alloc(PF_BLUETOOTH, prio, &sco_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 = sco_sock_destruct; sk->sk_sndtimeo = SCO_CONN_TIMEOUT; + + sock_reset_flag(sk, SOCK_ZAPPED); + + sk->sk_protocol = proto; sk->sk_state = BT_OPEN; sco_sock_init_timer(sk); @@ -631,8 +637,9 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, 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; @@ -778,7 +785,7 @@ static void sco_chan_del(struct sock *sk, int err) sk->sk_err = err; sk->sk_state_change(sk); - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); } static void sco_conn_ready(struct sco_conn *conn) @@ -886,93 +893,28 @@ drop: return 0; } -/* ---- Proc fs support ---- */ -#ifdef CONFIG_PROC_FS -static void *sco_seq_start(struct seq_file *seq, loff_t *pos) +static ssize_t sco_sysfs_show(struct class *dev, char *buf) { struct sock *sk; struct hlist_node *node; - loff_t l = *pos; + char *str = buf; read_lock_bh(&sco_sk_list.lock); - sk_for_each(sk, node, &sco_sk_list.head) - if (!l--) - goto found; - sk = NULL; -found: - return sk; -} - -static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos) -{ - struct sock *sk = e; - (*pos)++; - return sk_next(sk); -} + sk_for_each(sk, node, &sco_sk_list.head) { + str += sprintf(str, "%s %s %d\n", + batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + sk->sk_state); + } -static void sco_seq_stop(struct seq_file *seq, void *e) -{ read_unlock_bh(&sco_sk_list.lock); -} -static int sco_seq_show(struct seq_file *seq, void *e) -{ - struct sock *sk = e; - seq_printf(seq, "%s %s %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state); - return 0; + return (str - buf); } -static struct seq_operations sco_seq_ops = { - .start = sco_seq_start, - .next = sco_seq_next, - .stop = sco_seq_stop, - .show = sco_seq_show -}; - -static int sco_seq_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &sco_seq_ops); -} +static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); -static struct file_operations sco_seq_fops = { - .owner = THIS_MODULE, - .open = sco_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int __init sco_proc_init(void) -{ - struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt); - if (!p) - return -ENOMEM; - p->owner = THIS_MODULE; - p->proc_fops = &sco_seq_fops; - return 0; -} - -static void __exit sco_proc_cleanup(void) -{ - remove_proc_entry("sco", proc_bt); -} - -#else /* CONFIG_PROC_FS */ - -static int __init sco_proc_init(void) -{ - return 0; -} - -static void __exit sco_proc_cleanup(void) -{ - return; -} -#endif /* CONFIG_PROC_FS */ - -static struct proto_ops sco_sock_ops = { +static const struct proto_ops sco_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, .release = sco_sock_release, @@ -1011,36 +953,46 @@ static int __init sco_init(void) { int err; - if ((err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) { - BT_ERR("SCO socket registration failed"); + err = proto_register(&sco_proto, 0); + if (err < 0) return err; + + err = bt_sock_register(BTPROTO_SCO, &sco_sock_family_ops); + if (err < 0) { + BT_ERR("SCO socket registration failed"); + goto error; } - if ((err = hci_register_proto(&sco_hci_proto))) { + err = hci_register_proto(&sco_hci_proto); + if (err < 0) { BT_ERR("SCO protocol registration failed"); - return err; + bt_sock_unregister(BTPROTO_SCO); + goto error; } - sco_proc_init(); + class_create_file(&bt_class, &class_attr_sco); BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO socket layer initialized"); return 0; + +error: + proto_unregister(&sco_proto); + return err; } static void __exit sco_exit(void) { - int err; + class_remove_file(&bt_class, &class_attr_sco); - sco_proc_cleanup(); + if (bt_sock_unregister(BTPROTO_SCO) < 0) + BT_ERR("SCO socket unregistration failed"); - /* Unregister socket, protocol and notifier */ - if ((err = bt_sock_unregister(BTPROTO_SCO))) - BT_ERR("SCO socket unregistration failed. %d", err); + if (hci_unregister_proto(&sco_hci_proto) < 0) + BT_ERR("SCO protocol unregistration failed"); - if ((err = hci_unregister_proto(&sco_hci_proto))) - BT_ERR("SCO protocol unregistration failed. %d", err); + proto_unregister(&sco_proto); } module_init(sco_init);