net: use netdev_mc_count and netdev_mc_empty when appropriate
[safe/jmp/linux-2.6] / net / bluetooth / sco.c
index 71df982..dd8f6ec 100644 (file)
@@ -195,7 +195,7 @@ static int sco_connect(struct sock *sk)
        else
                type = SCO_LINK;
 
-       hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING);
+       hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
        if (!hcon)
                goto done;
 
@@ -359,20 +359,9 @@ static void sco_sock_kill(struct sock *sk)
        sock_put(sk);
 }
 
-/* Close socket.
- * Must be called on unlocked socket.
- */
-static void sco_sock_close(struct sock *sk)
+static void __sco_sock_close(struct sock *sk)
 {
-       struct sco_conn *conn;
-
-       sco_sock_clear_timer(sk);
-
-       lock_sock(sk);
-
-       conn = sco_pi(sk)->conn;
-
-       BT_DBG("sk %p state %d conn %p socket %p", sk, sk->sk_state, conn, sk->sk_socket);
+       BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
 
        switch (sk->sk_state) {
        case BT_LISTEN:
@@ -390,9 +379,15 @@ static void sco_sock_close(struct sock *sk)
                sock_set_flag(sk, SOCK_ZAPPED);
                break;
        }
+}
 
+/* Must be called on unlocked socket. */
+static void sco_sock_close(struct sock *sk)
+{
+       sco_sock_clear_timer(sk);
+       lock_sock(sk);
+       __sco_sock_close(sk);
        release_sock(sk);
-
        sco_sock_kill(sk);
 }
 
@@ -435,7 +430,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
        return sk;
 }
 
-static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
+static int sco_sock_create(struct net *net, struct socket *sock, int protocol,
+                          int kern)
 {
        struct sock *sk;
 
@@ -649,7 +645,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        return err;
 }
 
-static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
+static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
 {
        struct sock *sk = sock->sk;
        int err = 0;
@@ -748,6 +744,30 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
        return err;
 }
 
+static int sco_sock_shutdown(struct socket *sock, int how)
+{
+       struct sock *sk = sock->sk;
+       int err = 0;
+
+       BT_DBG("sock %p, sk %p", sock, sk);
+
+       if (!sk)
+               return 0;
+
+       lock_sock(sk);
+       if (!sk->sk_shutdown) {
+               sk->sk_shutdown = SHUTDOWN_MASK;
+               sco_sock_clear_timer(sk);
+               __sco_sock_close(sk);
+
+               if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
+                       err = bt_sock_wait_state(sk, BT_CLOSED,
+                                                       sk->sk_lingertime);
+       }
+       release_sock(sk);
+       return err;
+}
+
 static int sco_sock_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
@@ -902,7 +922,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
        return 0;
 }
 
-static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
+static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
 {
        BT_DBG("hcon %p reason %d", hcon, reason);
 
@@ -969,12 +989,12 @@ static const struct proto_ops sco_sock_ops = {
        .ioctl          = bt_sock_ioctl,
        .mmap           = sock_no_mmap,
        .socketpair     = sock_no_socketpair,
-       .shutdown       = sock_no_shutdown,
+       .shutdown       = sco_sock_shutdown,
        .setsockopt     = sco_sock_setsockopt,
        .getsockopt     = sco_sock_getsockopt
 };
 
-static struct net_proto_family sco_sock_family_ops = {
+static const struct net_proto_family sco_sock_family_ops = {
        .family = PF_BLUETOOTH,
        .owner  = THIS_MODULE,
        .create = sco_sock_create,
@@ -985,7 +1005,7 @@ static struct hci_proto sco_hci_proto = {
        .id             = HCI_PROTO_SCO,
        .connect_ind    = sco_connect_ind,
        .connect_cfm    = sco_connect_cfm,
-       .disconn_ind    = sco_disconn_ind,
+       .disconn_cfm    = sco_disconn_cfm,
        .recv_scodata   = sco_recv_scodata
 };