aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h4
-rw-r--r--net/bluetooth/hci_conn.c17
-rw-r--r--net/bluetooth/hci_event.c2
3 files changed, 22 insertions, 1 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c4ca4228b083..25b8a0345a6a 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -187,6 +187,7 @@ struct hci_conn {
187 struct work_struct work_del; 187 struct work_struct work_del;
188 188
189 struct device dev; 189 struct device dev;
190 atomic_t devref;
190 191
191 struct hci_dev *hdev; 192 struct hci_dev *hdev;
192 void *l2cap_data; 193 void *l2cap_data;
@@ -339,6 +340,9 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
339void hci_conn_enter_active_mode(struct hci_conn *conn); 340void hci_conn_enter_active_mode(struct hci_conn *conn);
340void hci_conn_enter_sniff_mode(struct hci_conn *conn); 341void hci_conn_enter_sniff_mode(struct hci_conn *conn);
341 342
343void hci_conn_hold_device(struct hci_conn *conn);
344void hci_conn_put_device(struct hci_conn *conn);
345
342static inline void hci_conn_hold(struct hci_conn *conn) 346static inline void hci_conn_hold(struct hci_conn *conn)
343{ 347{
344 atomic_inc(&conn->refcnt); 348 atomic_inc(&conn->refcnt);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fa47d5d84f5c..a9750984f772 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -246,6 +246,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
246 if (hdev->notify) 246 if (hdev->notify)
247 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); 247 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
248 248
249 atomic_set(&conn->devref, 0);
250
249 hci_conn_init_sysfs(conn); 251 hci_conn_init_sysfs(conn);
250 252
251 tasklet_enable(&hdev->tx_task); 253 tasklet_enable(&hdev->tx_task);
@@ -288,7 +290,7 @@ int hci_conn_del(struct hci_conn *conn)
288 290
289 skb_queue_purge(&conn->data_q); 291 skb_queue_purge(&conn->data_q);
290 292
291 hci_conn_del_sysfs(conn); 293 hci_conn_put_device(conn);
292 294
293 hci_dev_put(hdev); 295 hci_dev_put(hdev);
294 296
@@ -583,6 +585,19 @@ void hci_conn_check_pending(struct hci_dev *hdev)
583 hci_dev_unlock(hdev); 585 hci_dev_unlock(hdev);
584} 586}
585 587
588void hci_conn_hold_device(struct hci_conn *conn)
589{
590 atomic_inc(&conn->devref);
591}
592EXPORT_SYMBOL(hci_conn_hold_device);
593
594void hci_conn_put_device(struct hci_conn *conn)
595{
596 if (atomic_dec_and_test(&conn->devref))
597 hci_conn_del_sysfs(conn);
598}
599EXPORT_SYMBOL(hci_conn_put_device);
600
586int hci_get_conn_list(void __user *arg) 601int hci_get_conn_list(void __user *arg)
587{ 602{
588 struct hci_conn_list_req req, *cl; 603 struct hci_conn_list_req req, *cl;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 184ba0a88ec0..e99fe385fba2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -887,6 +887,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
887 } else 887 } else
888 conn->state = BT_CONNECTED; 888 conn->state = BT_CONNECTED;
889 889
890 hci_conn_hold_device(conn);
890 hci_conn_add_sysfs(conn); 891 hci_conn_add_sysfs(conn);
891 892
892 if (test_bit(HCI_AUTH, &hdev->flags)) 893 if (test_bit(HCI_AUTH, &hdev->flags))
@@ -1693,6 +1694,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
1693 conn->handle = __le16_to_cpu(ev->handle); 1694 conn->handle = __le16_to_cpu(ev->handle);
1694 conn->state = BT_CONNECTED; 1695 conn->state = BT_CONNECTED;
1695 1696
1697 hci_conn_hold_device(conn);
1696 hci_conn_add_sysfs(conn); 1698 hci_conn_add_sysfs(conn);
1697 break; 1699 break;
1698 1700