diff options
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r-- | net/bluetooth/hci_conn.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b9f90169940b..6c7f36379722 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -117,6 +117,16 @@ static void hci_acl_create_connection_cancel(struct hci_conn *conn) | |||
117 | hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); | 117 | hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp); |
118 | } | 118 | } |
119 | 119 | ||
120 | static void hci_reject_sco(struct hci_conn *conn) | ||
121 | { | ||
122 | struct hci_cp_reject_sync_conn_req cp; | ||
123 | |||
124 | cp.reason = HCI_ERROR_REMOTE_USER_TERM; | ||
125 | bacpy(&cp.bdaddr, &conn->dst); | ||
126 | |||
127 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); | ||
128 | } | ||
129 | |||
120 | void hci_disconnect(struct hci_conn *conn, __u8 reason) | 130 | void hci_disconnect(struct hci_conn *conn, __u8 reason) |
121 | { | 131 | { |
122 | struct hci_cp_disconnect cp; | 132 | struct hci_cp_disconnect cp; |
@@ -276,6 +286,8 @@ static void hci_conn_timeout(struct work_struct *work) | |||
276 | hci_acl_create_connection_cancel(conn); | 286 | hci_acl_create_connection_cancel(conn); |
277 | else if (conn->type == LE_LINK) | 287 | else if (conn->type == LE_LINK) |
278 | hci_le_create_connection_cancel(conn); | 288 | hci_le_create_connection_cancel(conn); |
289 | } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) { | ||
290 | hci_reject_sco(conn); | ||
279 | } | 291 | } |
280 | break; | 292 | break; |
281 | case BT_CONFIG: | 293 | case BT_CONFIG: |
@@ -398,8 +410,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
398 | if (hdev->notify) | 410 | if (hdev->notify) |
399 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); | 411 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); |
400 | 412 | ||
401 | atomic_set(&conn->devref, 0); | ||
402 | |||
403 | hci_conn_init_sysfs(conn); | 413 | hci_conn_init_sysfs(conn); |
404 | 414 | ||
405 | return conn; | 415 | return conn; |
@@ -433,7 +443,7 @@ int hci_conn_del(struct hci_conn *conn) | |||
433 | struct hci_conn *acl = conn->link; | 443 | struct hci_conn *acl = conn->link; |
434 | if (acl) { | 444 | if (acl) { |
435 | acl->link = NULL; | 445 | acl->link = NULL; |
436 | hci_conn_put(acl); | 446 | hci_conn_drop(acl); |
437 | } | 447 | } |
438 | } | 448 | } |
439 | 449 | ||
@@ -448,12 +458,11 @@ int hci_conn_del(struct hci_conn *conn) | |||
448 | 458 | ||
449 | skb_queue_purge(&conn->data_q); | 459 | skb_queue_purge(&conn->data_q); |
450 | 460 | ||
451 | hci_conn_put_device(conn); | 461 | hci_conn_del_sysfs(conn); |
452 | 462 | ||
453 | hci_dev_put(hdev); | 463 | hci_dev_put(hdev); |
454 | 464 | ||
455 | if (conn->handle == 0) | 465 | hci_conn_put(conn); |
456 | kfree(conn); | ||
457 | 466 | ||
458 | return 0; | 467 | return 0; |
459 | } | 468 | } |
@@ -565,7 +574,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, | |||
565 | if (!sco) { | 574 | if (!sco) { |
566 | sco = hci_conn_add(hdev, type, dst); | 575 | sco = hci_conn_add(hdev, type, dst); |
567 | if (!sco) { | 576 | if (!sco) { |
568 | hci_conn_put(acl); | 577 | hci_conn_drop(acl); |
569 | return ERR_PTR(-ENOMEM); | 578 | return ERR_PTR(-ENOMEM); |
570 | } | 579 | } |
571 | } | 580 | } |
@@ -835,19 +844,6 @@ void hci_conn_check_pending(struct hci_dev *hdev) | |||
835 | hci_dev_unlock(hdev); | 844 | hci_dev_unlock(hdev); |
836 | } | 845 | } |
837 | 846 | ||
838 | void hci_conn_hold_device(struct hci_conn *conn) | ||
839 | { | ||
840 | atomic_inc(&conn->devref); | ||
841 | } | ||
842 | EXPORT_SYMBOL(hci_conn_hold_device); | ||
843 | |||
844 | void hci_conn_put_device(struct hci_conn *conn) | ||
845 | { | ||
846 | if (atomic_dec_and_test(&conn->devref)) | ||
847 | hci_conn_del_sysfs(conn); | ||
848 | } | ||
849 | EXPORT_SYMBOL(hci_conn_put_device); | ||
850 | |||
851 | int hci_get_conn_list(void __user *arg) | 847 | int hci_get_conn_list(void __user *arg) |
852 | { | 848 | { |
853 | struct hci_conn *c; | 849 | struct hci_conn *c; |
@@ -980,7 +976,7 @@ void hci_chan_del(struct hci_chan *chan) | |||
980 | 976 | ||
981 | synchronize_rcu(); | 977 | synchronize_rcu(); |
982 | 978 | ||
983 | hci_conn_put(conn); | 979 | hci_conn_drop(conn); |
984 | 980 | ||
985 | skb_queue_purge(&chan->data_q); | 981 | skb_queue_purge(&chan->data_q); |
986 | kfree(chan); | 982 | kfree(chan); |