Bluetooth: Track feature pages in a single table
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / bluetooth / hci_conn.c
index 4925a02ae7e4db7df4d4cdfc972e68375743861c..6c7f3637972254c9bbbe0b5a9c6f007ba1ec41e2 100644 (file)
@@ -117,7 +117,17 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn)
        hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
 }
 
-void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
+static void hci_reject_sco(struct hci_conn *conn)
+{
+       struct hci_cp_reject_sync_conn_req cp;
+
+       cp.reason = HCI_ERROR_REMOTE_USER_TERM;
+       bacpy(&cp.bdaddr, &conn->dst);
+
+       hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp);
+}
+
+void hci_disconnect(struct hci_conn *conn, __u8 reason)
 {
        struct hci_cp_disconnect cp;
 
@@ -253,7 +263,7 @@ static void hci_conn_disconnect(struct hci_conn *conn)
                hci_amp_disconn(conn, reason);
                break;
        default:
-               hci_acl_disconn(conn, reason);
+               hci_disconnect(conn, reason);
                break;
        }
 }
@@ -276,6 +286,8 @@ static void hci_conn_timeout(struct work_struct *work)
                                hci_acl_create_connection_cancel(conn);
                        else if (conn->type == LE_LINK)
                                hci_le_create_connection_cancel(conn);
+               } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
+                       hci_reject_sco(conn);
                }
                break;
        case BT_CONFIG:
@@ -398,8 +410,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
        if (hdev->notify)
                hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
 
-       atomic_set(&conn->devref, 0);
-
        hci_conn_init_sysfs(conn);
 
        return conn;
@@ -433,7 +443,7 @@ int hci_conn_del(struct hci_conn *conn)
                struct hci_conn *acl = conn->link;
                if (acl) {
                        acl->link = NULL;
-                       hci_conn_put(acl);
+                       hci_conn_drop(acl);
                }
        }
 
@@ -448,12 +458,11 @@ int hci_conn_del(struct hci_conn *conn)
 
        skb_queue_purge(&conn->data_q);
 
-       hci_conn_put_device(conn);
+       hci_conn_del_sysfs(conn);
 
        hci_dev_put(hdev);
 
-       if (conn->handle == 0)
-               kfree(conn);
+       hci_conn_put(conn);
 
        return 0;
 }
@@ -565,7 +574,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
        if (!sco) {
                sco = hci_conn_add(hdev, type, dst);
                if (!sco) {
-                       hci_conn_put(acl);
+                       hci_conn_drop(acl);
                        return ERR_PTR(-ENOMEM);
                }
        }
@@ -835,19 +844,6 @@ void hci_conn_check_pending(struct hci_dev *hdev)
        hci_dev_unlock(hdev);
 }
 
-void hci_conn_hold_device(struct hci_conn *conn)
-{
-       atomic_inc(&conn->devref);
-}
-EXPORT_SYMBOL(hci_conn_hold_device);
-
-void hci_conn_put_device(struct hci_conn *conn)
-{
-       if (atomic_dec_and_test(&conn->devref))
-               hci_conn_del_sysfs(conn);
-}
-EXPORT_SYMBOL(hci_conn_put_device);
-
 int hci_get_conn_list(void __user *arg)
 {
        struct hci_conn *c;
@@ -980,7 +976,7 @@ void hci_chan_del(struct hci_chan *chan)
 
        synchronize_rcu();
 
-       hci_conn_put(conn);
+       hci_conn_drop(conn);
 
        skb_queue_purge(&chan->data_q);
        kfree(chan);