aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c10
-rw-r--r--net/bluetooth/hci_event.c36
-rw-r--r--net/bluetooth/hci_sysfs.c37
3 files changed, 55 insertions, 28 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 1181db08d9de..375f4b4f7f79 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -215,6 +215,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
215 conn->state = BT_OPEN; 215 conn->state = BT_OPEN;
216 216
217 conn->power_save = 1; 217 conn->power_save = 1;
218 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
218 219
219 switch (type) { 220 switch (type) {
220 case ACL_LINK: 221 case ACL_LINK:
@@ -424,12 +425,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
424 if (sec_level == BT_SECURITY_SDP) 425 if (sec_level == BT_SECURITY_SDP)
425 return 1; 426 return 1;
426 427
427 if (sec_level == BT_SECURITY_LOW) { 428 if (sec_level == BT_SECURITY_LOW &&
428 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) 429 (!conn->ssp_mode || !conn->hdev->ssp_mode))
429 return hci_conn_auth(conn, sec_level, auth_type); 430 return 1;
430 else
431 return 1;
432 }
433 431
434 if (conn->link_mode & HCI_LM_ENCRYPT) 432 if (conn->link_mode & HCI_LM_ENCRYPT)
435 return hci_conn_auth(conn, sec_level, auth_type); 433 return hci_conn_auth(conn, sec_level, auth_type);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 15f40ea8d544..4e7cb88e5da9 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -883,6 +883,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
883 if (conn->type == ACL_LINK) { 883 if (conn->type == ACL_LINK) {
884 conn->state = BT_CONFIG; 884 conn->state = BT_CONFIG;
885 hci_conn_hold(conn); 885 hci_conn_hold(conn);
886 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
886 } else 887 } else
887 conn->state = BT_CONNECTED; 888 conn->state = BT_CONNECTED;
888 889
@@ -1063,9 +1064,14 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
1063 hci_proto_connect_cfm(conn, ev->status); 1064 hci_proto_connect_cfm(conn, ev->status);
1064 hci_conn_put(conn); 1065 hci_conn_put(conn);
1065 } 1066 }
1066 } else 1067 } else {
1067 hci_auth_cfm(conn, ev->status); 1068 hci_auth_cfm(conn, ev->status);
1068 1069
1070 hci_conn_hold(conn);
1071 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1072 hci_conn_put(conn);
1073 }
1074
1069 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1075 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1070 if (!ev->status) { 1076 if (!ev->status) {
1071 struct hci_cp_set_conn_encrypt cp; 1077 struct hci_cp_set_conn_encrypt cp;
@@ -1479,7 +1485,21 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
1479 1485
1480static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 1486static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1481{ 1487{
1488 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1489 struct hci_conn *conn;
1490
1482 BT_DBG("%s", hdev->name); 1491 BT_DBG("%s", hdev->name);
1492
1493 hci_dev_lock(hdev);
1494
1495 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1496 if (conn) {
1497 hci_conn_hold(conn);
1498 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1499 hci_conn_put(conn);
1500 }
1501
1502 hci_dev_unlock(hdev);
1483} 1503}
1484 1504
1485static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 1505static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
@@ -1489,7 +1509,21 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
1489 1509
1490static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 1510static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1491{ 1511{
1512 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1513 struct hci_conn *conn;
1514
1492 BT_DBG("%s", hdev->name); 1515 BT_DBG("%s", hdev->name);
1516
1517 hci_dev_lock(hdev);
1518
1519 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1520 if (conn) {
1521 hci_conn_hold(conn);
1522 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1523 hci_conn_put(conn);
1524 }
1525
1526 hci_dev_unlock(hdev);
1493} 1527}
1494 1528
1495static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) 1529static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ed82796d4a0f..b7c51082ddeb 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -9,8 +9,7 @@
9struct class *bt_class = NULL; 9struct class *bt_class = NULL;
10EXPORT_SYMBOL_GPL(bt_class); 10EXPORT_SYMBOL_GPL(bt_class);
11 11
12static struct workqueue_struct *btaddconn; 12static struct workqueue_struct *bluetooth;
13static struct workqueue_struct *btdelconn;
14 13
15static inline char *link_typetostr(int type) 14static inline char *link_typetostr(int type)
16{ 15{
@@ -88,9 +87,10 @@ static struct device_type bt_link = {
88 87
89static void add_conn(struct work_struct *work) 88static void add_conn(struct work_struct *work)
90{ 89{
91 struct hci_conn *conn = container_of(work, struct hci_conn, work); 90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
92 91
93 flush_workqueue(btdelconn); 92 /* ensure previous add/del is complete */
93 flush_workqueue(bluetooth);
94 94
95 if (device_add(&conn->dev) < 0) { 95 if (device_add(&conn->dev) < 0) {
96 BT_ERR("Failed to register connection device"); 96 BT_ERR("Failed to register connection device");
@@ -114,9 +114,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
114 114
115 device_initialize(&conn->dev); 115 device_initialize(&conn->dev);
116 116
117 INIT_WORK(&conn->work, add_conn); 117 INIT_WORK(&conn->work_add, add_conn);
118 118
119 queue_work(btaddconn, &conn->work); 119 queue_work(bluetooth, &conn->work_add);
120} 120}
121 121
122/* 122/*
@@ -131,9 +131,12 @@ static int __match_tty(struct device *dev, void *data)
131 131
132static void del_conn(struct work_struct *work) 132static void del_conn(struct work_struct *work)
133{ 133{
134 struct hci_conn *conn = container_of(work, struct hci_conn, work); 134 struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
135 struct hci_dev *hdev = conn->hdev; 135 struct hci_dev *hdev = conn->hdev;
136 136
137 /* ensure previous add/del is complete */
138 flush_workqueue(bluetooth);
139
137 while (1) { 140 while (1) {
138 struct device *dev; 141 struct device *dev;
139 142
@@ -156,9 +159,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
156 if (!device_is_registered(&conn->dev)) 159 if (!device_is_registered(&conn->dev))
157 return; 160 return;
158 161
159 INIT_WORK(&conn->work, del_conn); 162 INIT_WORK(&conn->work_del, del_conn);
160 163
161 queue_work(btdelconn, &conn->work); 164 queue_work(bluetooth, &conn->work_del);
162} 165}
163 166
164static inline char *host_typetostr(int type) 167static inline char *host_typetostr(int type)
@@ -435,20 +438,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
435 438
436int __init bt_sysfs_init(void) 439int __init bt_sysfs_init(void)
437{ 440{
438 btaddconn = create_singlethread_workqueue("btaddconn"); 441 bluetooth = create_singlethread_workqueue("bluetooth");
439 if (!btaddconn) 442 if (!bluetooth)
440 return -ENOMEM;
441
442 btdelconn = create_singlethread_workqueue("btdelconn");
443 if (!btdelconn) {
444 destroy_workqueue(btaddconn);
445 return -ENOMEM; 443 return -ENOMEM;
446 }
447 444
448 bt_class = class_create(THIS_MODULE, "bluetooth"); 445 bt_class = class_create(THIS_MODULE, "bluetooth");
449 if (IS_ERR(bt_class)) { 446 if (IS_ERR(bt_class)) {
450 destroy_workqueue(btdelconn); 447 destroy_workqueue(bluetooth);
451 destroy_workqueue(btaddconn);
452 return PTR_ERR(bt_class); 448 return PTR_ERR(bt_class);
453 } 449 }
454 450
@@ -457,8 +453,7 @@ int __init bt_sysfs_init(void)
457 453
458void bt_sysfs_cleanup(void) 454void bt_sysfs_cleanup(void)
459{ 455{
460 destroy_workqueue(btaddconn); 456 destroy_workqueue(bluetooth);
461 destroy_workqueue(btdelconn);
462 457
463 class_destroy(bt_class); 458 class_destroy(bt_class);
464} 459}