vserver 2.0 rc7
[linux-2.6.git] / net / bluetooth / hci_event.c
index 47a1e90..c4b592b 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/major.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
@@ -718,17 +717,20 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
 
        BT_DBG("%s status %d", hdev->name, ev->status);
 
-       if (ev->status)
-               return;
-
        hci_dev_lock(hdev);
 
        conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
        if (conn) {
-               if (ev->role)
-                       conn->link_mode &= ~HCI_LM_MASTER;
-               else
-                       conn->link_mode |= HCI_LM_MASTER;
+               if (!ev->status) {
+                       if (ev->role)
+                               conn->link_mode &= ~HCI_LM_MASTER;
+                       else
+                               conn->link_mode |= HCI_LM_MASTER;
+               }
+
+               clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+
+               hci_role_switch_cfm(conn, ev->status, ev->role);
        }
 
        hci_dev_unlock(hdev);
@@ -749,6 +751,7 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        if (conn) {
                if (!ev->status)
                        conn->link_mode |= HCI_LM_AUTH;
+
                clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
 
                hci_auth_cfm(conn, ev->status);
@@ -790,6 +793,7 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
                        else
                                conn->link_mode &= ~HCI_LM_ENCRYPT;
                }
+
                clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
 
                hci_encrypt_cfm(conn, ev->status, ev->encrypt);
@@ -801,6 +805,25 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
 /* Change Connection Link Key Complete */
 static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
+       struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
+       struct hci_conn *conn = NULL;
+       __u16 handle = __le16_to_cpu(ev->handle);
+
+       BT_DBG("%s status %d", hdev->name, ev->status);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
+       if (conn) {
+               if (!ev->status)
+                       conn->link_mode |= HCI_LM_SECURE;
+
+               clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
+
+               hci_key_change_cfm(conn, ev->status);
+       }
+
+       hci_dev_unlock(hdev);
 }
 
 /* Pin Code Request*/