Bluetooth: Ignore Tx Window value with Streaming mode
[safe/jmp/linux-2.6] / net / bluetooth / hci_sock.c
index 43dd637..38f08f6 100644 (file)
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-#ifndef CONFIG_BT_HCI_SOCK_DEBUG
-#undef  BT_DBG
-#define BT_DBG(D...)
-#endif
-
 /* ----- HCI socket interface ----- */
 
 static inline int hci_test_bit(int nr, void *addr)
@@ -84,7 +79,7 @@ static struct hci_sec_filter hci_sec_filter = {
 };
 
 static struct bt_sock_list hci_sk_list = {
-       .lock = RW_LOCK_UNLOCKED
+       .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
 };
 
 /* Send frame to RAW socket */
@@ -193,19 +188,11 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
 
                return 0;
 
-       case HCISETSECMGR:
-               if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
-
-               if (arg)
-                       set_bit(HCI_SECMGR, &hdev->flags);
-               else
-                       clear_bit(HCI_SECMGR, &hdev->flags);
-
-               return 0;
-
        case HCIGETCONNINFO:
-               return hci_get_conn_info(hdev, (void __user *)arg);
+               return hci_get_conn_info(hdev, (void __user *) arg);
+
+       case HCIGETAUTHINFO:
+               return hci_get_auth_info(hdev, (void __user *) arg);
 
        default:
                if (hdev->ioctl)
@@ -217,7 +204,7 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
 static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
-       void __user *argp = (void __user *)arg;
+       void __user *argp = (void __user *) arg;
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);
@@ -342,6 +329,9 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_
        }
 
        if (mask & HCI_CMSG_TSTAMP) {
+#ifdef CONFIG_COMPAT
+               struct compat_timeval ctv;
+#endif
                struct timeval tv;
                void *data;
                int len;
@@ -352,7 +342,6 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_
                len = sizeof(tv);
 #ifdef CONFIG_COMPAT
                if (msg->msg_flags & MSG_CMSG_COMPAT) {
-                       struct compat_timeval ctv;
                        ctv.tv_sec = tv.tv_sec;
                        ctv.tv_usec = tv.tv_usec;
                        data = &ctv;
@@ -427,6 +416,11 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                goto done;
        }
 
+       if (!test_bit(HCI_UP, &hdev->flags)) {
+               err = -ENETDOWN;
+               goto done;
+       }
+
        if (!(skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
                goto done;
 
@@ -440,7 +434,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        skb->dev = (void *) hdev;
 
        if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
-               u16 opcode = __le16_to_cpu(get_unaligned((__le16 *) skb->data));
+               u16 opcode = get_unaligned_le16(skb->data);
                u16 ogf = hci_opcode_ogf(opcode);
                u16 ocf = hci_opcode_ocf(opcode);
 
@@ -451,12 +445,12 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        goto drop;
                }
 
-               if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
+               if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
                        skb_queue_tail(&hdev->raw_q, skb);
-                       hci_sched_tx(hdev);
+                       tasklet_schedule(&hdev->tx_task);
                } else {
                        skb_queue_tail(&hdev->cmd_q, skb);
-                       hci_sched_cmd(hdev);
+                       tasklet_schedule(&hdev->cmd_task);
                }
        } else {
                if (!capable(CAP_NET_RAW)) {
@@ -465,7 +459,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                }
 
                skb_queue_tail(&hdev->raw_q, skb);
-               hci_sched_tx(hdev);
+               tasklet_schedule(&hdev->tx_task);
        }
 
        err = len;
@@ -479,7 +473,7 @@ drop:
        goto done;
 }
 
-static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
 {
        struct hci_ufilter uf = { .opcode = 0 };
        struct sock *sk = sock->sk;
@@ -634,7 +628,8 @@ static struct proto hci_sk_proto = {
        .obj_size       = sizeof(struct hci_pinfo)
 };
 
-static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
+static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
+                          int kern)
 {
        struct sock *sk;
 
@@ -645,7 +640,7 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
 
        sock->ops = &hci_sock_ops;
 
-       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto);
        if (!sk)
                return -ENOMEM;
 
@@ -700,7 +695,7 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
        return NOTIFY_DONE;
 }
 
-static struct net_proto_family hci_sock_family_ops = {
+static const struct net_proto_family hci_sock_family_ops = {
        .family = PF_BLUETOOTH,
        .owner  = THIS_MODULE,
        .create = hci_sock_create,
@@ -734,7 +729,7 @@ error:
        return err;
 }
 
-int __exit hci_sock_cleanup(void)
+void __exit hci_sock_cleanup(void)
 {
        if (bt_sock_unregister(BTPROTO_HCI) < 0)
                BT_ERR("HCI socket unregistration failed");
@@ -742,6 +737,4 @@ int __exit hci_sock_cleanup(void)
        hci_unregister_notifier(&hci_sock_nblock);
 
        proto_unregister(&hci_sk_proto);
-
-       return 0;
 }