Bluetooth: Fix issue with sysfs handling for connections
[safe/jmp/linux-2.6] / include / net / bluetooth / hci_core.h
index 4b14972..73aead2 100644 (file)
@@ -171,6 +171,7 @@ struct hci_conn {
        __u8             auth_type;
        __u8             sec_level;
        __u8             power_save;
+       __u16            disc_timeout;
        unsigned long    pend;
 
        unsigned int     sent;
@@ -180,7 +181,8 @@ struct hci_conn {
        struct timer_list disc_timer;
        struct timer_list idle_timer;
 
-       struct work_struct work;
+       struct work_struct work_add;
+       struct work_struct work_del;
 
        struct device   dev;
 
@@ -328,7 +330,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
 
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
 int hci_conn_check_link_mode(struct hci_conn *conn);
-int hci_conn_security(struct hci_conn *conn, __u8 sec_level);
+int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
 int hci_conn_change_link_key(struct hci_conn *conn);
 int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 
@@ -348,9 +350,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
                if (conn->type == ACL_LINK) {
                        del_timer(&conn->idle_timer);
                        if (conn->state == BT_CONNECTED) {
-                               timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT);
+                               timeo = msecs_to_jiffies(conn->disc_timeout);
                                if (!conn->out)
-                                       timeo *= 5;
+                                       timeo *= 2;
                        } else
                                timeo = msecs_to_jiffies(10);
                } else
@@ -455,6 +457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
 
 int hci_register_sysfs(struct hci_dev *hdev);
 void hci_unregister_sysfs(struct hci_dev *hdev);
+void hci_conn_init_sysfs(struct hci_conn *conn);
 void hci_conn_add_sysfs(struct hci_conn *conn);
 void hci_conn_del_sysfs(struct hci_conn *conn);
 
@@ -478,7 +481,8 @@ struct hci_proto {
 
        int (*connect_ind)      (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
        int (*connect_cfm)      (struct hci_conn *conn, __u8 status);
-       int (*disconn_ind)      (struct hci_conn *conn, __u8 reason);
+       int (*disconn_ind)      (struct hci_conn *conn);
+       int (*disconn_cfm)      (struct hci_conn *conn, __u8 reason);
        int (*recv_acldata)     (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
        int (*recv_scodata)     (struct hci_conn *conn, struct sk_buff *skb);
        int (*security_cfm)     (struct hci_conn *conn, __u8 status, __u8 encrypt);
@@ -513,17 +517,33 @@ static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
                hp->connect_cfm(conn, status);
 }
 
-static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
+static inline int hci_proto_disconn_ind(struct hci_conn *conn)
 {
        register struct hci_proto *hp;
+       int reason = 0x13;
 
        hp = hci_proto[HCI_PROTO_L2CAP];
        if (hp && hp->disconn_ind)
-               hp->disconn_ind(conn, reason);
+               reason = hp->disconn_ind(conn);
 
        hp = hci_proto[HCI_PROTO_SCO];
        if (hp && hp->disconn_ind)
-               hp->disconn_ind(conn, reason);
+               reason = hp->disconn_ind(conn);
+
+       return reason;
+}
+
+static inline void hci_proto_disconn_cfm(struct hci_conn *conn, __u8 reason)
+{
+       register struct hci_proto *hp;
+
+       hp = hci_proto[HCI_PROTO_L2CAP];
+       if (hp && hp->disconn_cfm)
+               hp->disconn_cfm(conn, reason);
+
+       hp = hci_proto[HCI_PROTO_SCO];
+       if (hp && hp->disconn_cfm)
+               hp->disconn_cfm(conn, reason);
 }
 
 static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
@@ -597,6 +617,9 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr
 {
        struct list_head *p;
 
+       if (conn->sec_level == BT_SECURITY_SDP)
+               conn->sec_level = BT_SECURITY_LOW;
+
        hci_proto_encrypt_cfm(conn, status, encrypt);
 
        read_lock_bh(&hci_cb_list_lock);