X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbluetooth%2Fsco.c;h=746c11fc017e9b8e73320ac126e68a607d02e76a;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=55a26670578863fb4298b4021a60f9691e85f7d7;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 55a266705..746c11fc0 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -56,7 +55,7 @@ #define BT_DBG(D...) #endif -#define VERSION "0.3" +#define VERSION "0.4" static struct proto_ops sco_sock_ops; @@ -334,9 +333,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 +348,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 +356,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 +395,7 @@ static void sco_sock_close(struct sock *sk) break; default: - sk->sk_zapped = 1; + sock_set_flag(sk, SOCK_ZAPPED); break; }; @@ -416,18 +412,29 @@ static void sco_sock_init(struct sock *sk, struct sock *parent) sk->sk_type = parent->sk_type; } +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, int 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); @@ -705,6 +712,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char } cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle; + memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); len = min_t(unsigned int, len, sizeof(cinfo)); if (copy_to_user(optval, (char *)&cinfo, len)) @@ -777,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) @@ -1010,14 +1018,21 @@ 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(); @@ -1026,26 +1041,29 @@ static int __init sco_init(void) BT_INFO("SCO socket layer initialized"); return 0; + +error: + proto_unregister(&sco_proto); + return err; } static void __exit sco_exit(void) { - int err; - sco_proc_cleanup(); - /* Unregister socket, protocol and notifier */ - if ((err = bt_sock_unregister(BTPROTO_SCO))) - BT_ERR("SCO socket unregistration failed. %d", err); + if (bt_sock_unregister(BTPROTO_SCO) < 0) + BT_ERR("SCO socket unregistration failed"); + + 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); module_exit(sco_exit); -MODULE_AUTHOR("Maxim Krasnyansky "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION); MODULE_VERSION(VERSION); MODULE_LICENSE("GPL");