aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c76
1 files changed, 70 insertions, 6 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b9196a44f759..25bfce0666eb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -130,6 +130,20 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
130 hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); 130 hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
131} 131}
132 132
133static void hci_amp_disconn(struct hci_conn *conn, __u8 reason)
134{
135 struct hci_cp_disconn_phy_link cp;
136
137 BT_DBG("hcon %p", conn);
138
139 conn->state = BT_DISCONN;
140
141 cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
142 cp.reason = reason;
143 hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
144 sizeof(cp), &cp);
145}
146
133static void hci_add_sco(struct hci_conn *conn, __u16 handle) 147static void hci_add_sco(struct hci_conn *conn, __u16 handle)
134{ 148{
135 struct hci_dev *hdev = conn->hdev; 149 struct hci_dev *hdev = conn->hdev;
@@ -230,11 +244,24 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status)
230 } 244 }
231} 245}
232 246
247static void hci_conn_disconnect(struct hci_conn *conn)
248{
249 __u8 reason = hci_proto_disconn_ind(conn);
250
251 switch (conn->type) {
252 case ACL_LINK:
253 hci_acl_disconn(conn, reason);
254 break;
255 case AMP_LINK:
256 hci_amp_disconn(conn, reason);
257 break;
258 }
259}
260
233static void hci_conn_timeout(struct work_struct *work) 261static void hci_conn_timeout(struct work_struct *work)
234{ 262{
235 struct hci_conn *conn = container_of(work, struct hci_conn, 263 struct hci_conn *conn = container_of(work, struct hci_conn,
236 disc_work.work); 264 disc_work.work);
237 __u8 reason;
238 265
239 BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); 266 BT_DBG("hcon %p state %s", conn, state_to_string(conn->state));
240 267
@@ -253,8 +280,7 @@ static void hci_conn_timeout(struct work_struct *work)
253 break; 280 break;
254 case BT_CONFIG: 281 case BT_CONFIG:
255 case BT_CONNECTED: 282 case BT_CONNECTED:
256 reason = hci_proto_disconn_ind(conn); 283 hci_conn_disconnect(conn);
257 hci_acl_disconn(conn, reason);
258 break; 284 break;
259 default: 285 default:
260 conn->state = BT_CLOSED; 286 conn->state = BT_CLOSED;
@@ -320,7 +346,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
320{ 346{
321 struct hci_conn *conn; 347 struct hci_conn *conn;
322 348
323 BT_DBG("%s dst %s", hdev->name, batostr(dst)); 349 BT_DBG("%s dst %pMR", hdev->name, dst);
324 350
325 conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL); 351 conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
326 if (!conn) 352 if (!conn)
@@ -437,7 +463,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
437 int use_src = bacmp(src, BDADDR_ANY); 463 int use_src = bacmp(src, BDADDR_ANY);
438 struct hci_dev *hdev = NULL, *d; 464 struct hci_dev *hdev = NULL, *d;
439 465
440 BT_DBG("%s -> %s", batostr(src), batostr(dst)); 466 BT_DBG("%pMR -> %pMR", src, dst);
441 467
442 read_lock(&hci_dev_list_lock); 468 read_lock(&hci_dev_list_lock);
443 469
@@ -476,6 +502,9 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
476{ 502{
477 struct hci_conn *le; 503 struct hci_conn *le;
478 504
505 if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags))
506 return ERR_PTR(-ENOTSUPP);
507
479 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); 508 le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst);
480 if (!le) { 509 if (!le) {
481 le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); 510 le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
@@ -567,7 +596,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
567struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, 596struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
568 __u8 dst_type, __u8 sec_level, __u8 auth_type) 597 __u8 dst_type, __u8 sec_level, __u8 auth_type)
569{ 598{
570 BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type); 599 BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type);
571 600
572 switch (type) { 601 switch (type) {
573 case LE_LINK: 602 case LE_LINK:
@@ -933,6 +962,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn)
933 962
934 chan->conn = conn; 963 chan->conn = conn;
935 skb_queue_head_init(&chan->data_q); 964 skb_queue_head_init(&chan->data_q);
965 chan->state = BT_CONNECTED;
936 966
937 list_add_rcu(&chan->list, &conn->chan_list); 967 list_add_rcu(&chan->list, &conn->chan_list);
938 968
@@ -950,6 +980,8 @@ void hci_chan_del(struct hci_chan *chan)
950 980
951 synchronize_rcu(); 981 synchronize_rcu();
952 982
983 hci_conn_put(conn);
984
953 skb_queue_purge(&chan->data_q); 985 skb_queue_purge(&chan->data_q);
954 kfree(chan); 986 kfree(chan);
955} 987}
@@ -963,3 +995,35 @@ void hci_chan_list_flush(struct hci_conn *conn)
963 list_for_each_entry_safe(chan, n, &conn->chan_list, list) 995 list_for_each_entry_safe(chan, n, &conn->chan_list, list)
964 hci_chan_del(chan); 996 hci_chan_del(chan);
965} 997}
998
999static struct hci_chan *__hci_chan_lookup_handle(struct hci_conn *hcon,
1000 __u16 handle)
1001{
1002 struct hci_chan *hchan;
1003
1004 list_for_each_entry(hchan, &hcon->chan_list, list) {
1005 if (hchan->handle == handle)
1006 return hchan;
1007 }
1008
1009 return NULL;
1010}
1011
1012struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle)
1013{
1014 struct hci_conn_hash *h = &hdev->conn_hash;
1015 struct hci_conn *hcon;
1016 struct hci_chan *hchan = NULL;
1017
1018 rcu_read_lock();
1019
1020 list_for_each_entry_rcu(hcon, &h->list, list) {
1021 hchan = __hci_chan_lookup_handle(hcon, handle);
1022 if (hchan)
1023 break;
1024 }
1025
1026 rcu_read_unlock();
1027
1028 return hchan;
1029}