aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-05-07 05:17:13 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-07 05:17:34 -0400
commit44347d947f628060b92449702071bfe1d31dfb75 (patch)
treec6ed74610d5b3295df4296659f80f5feb94b28cc /net/bluetooth
parentd94fc523f3c35bd8013f04827e94756cbc0212f4 (diff)
parent413f81eba35d6ede9289b0c8a920c013a84fac71 (diff)
Merge branch 'linus' into tracing/core
Merge reason: tracing/core was on a .30-rc1 base and was missing out on on a handful of tracing fixes present in .30-rc5-almost. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_conn.c12
-rw-r--r--net/bluetooth/hci_event.c74
-rw-r--r--net/bluetooth/hci_sysfs.c87
-rw-r--r--net/bluetooth/rfcomm/core.c2
4 files changed, 114 insertions, 61 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 1181db08d9de..61309b26f271 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:
@@ -247,6 +248,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
247 if (hdev->notify) 248 if (hdev->notify)
248 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); 249 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
249 250
251 hci_conn_init_sysfs(conn);
252
250 tasklet_enable(&hdev->tx_task); 253 tasklet_enable(&hdev->tx_task);
251 254
252 return conn; 255 return conn;
@@ -424,12 +427,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
424 if (sec_level == BT_SECURITY_SDP) 427 if (sec_level == BT_SECURITY_SDP)
425 return 1; 428 return 1;
426 429
427 if (sec_level == BT_SECURITY_LOW) { 430 if (sec_level == BT_SECURITY_LOW &&
428 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) 431 (!conn->ssp_mode || !conn->hdev->ssp_mode))
429 return hci_conn_auth(conn, sec_level, auth_type); 432 return 1;
430 else
431 return 1;
432 }
433 433
434 if (conn->link_mode & HCI_LM_ENCRYPT) 434 if (conn->link_mode & HCI_LM_ENCRYPT)
435 return hci_conn_auth(conn, sec_level, auth_type); 435 return hci_conn_auth(conn, sec_level, auth_type);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 55534244c3a0..4e7cb88e5da9 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -866,8 +866,16 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
866 hci_dev_lock(hdev); 866 hci_dev_lock(hdev);
867 867
868 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); 868 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
869 if (!conn) 869 if (!conn) {
870 goto unlock; 870 if (ev->link_type != SCO_LINK)
871 goto unlock;
872
873 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
874 if (!conn)
875 goto unlock;
876
877 conn->type = SCO_LINK;
878 }
871 879
872 if (!ev->status) { 880 if (!ev->status) {
873 conn->handle = __le16_to_cpu(ev->handle); 881 conn->handle = __le16_to_cpu(ev->handle);
@@ -875,6 +883,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
875 if (conn->type == ACL_LINK) { 883 if (conn->type == ACL_LINK) {
876 conn->state = BT_CONFIG; 884 conn->state = BT_CONFIG;
877 hci_conn_hold(conn); 885 hci_conn_hold(conn);
886 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
878 } else 887 } else
879 conn->state = BT_CONNECTED; 888 conn->state = BT_CONNECTED;
880 889
@@ -1055,9 +1064,14 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
1055 hci_proto_connect_cfm(conn, ev->status); 1064 hci_proto_connect_cfm(conn, ev->status);
1056 hci_conn_put(conn); 1065 hci_conn_put(conn);
1057 } 1066 }
1058 } else 1067 } else {
1059 hci_auth_cfm(conn, ev->status); 1068 hci_auth_cfm(conn, ev->status);
1060 1069
1070 hci_conn_hold(conn);
1071 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1072 hci_conn_put(conn);
1073 }
1074
1061 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1075 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1062 if (!ev->status) { 1076 if (!ev->status) {
1063 struct hci_cp_set_conn_encrypt cp; 1077 struct hci_cp_set_conn_encrypt cp;
@@ -1471,7 +1485,21 @@ static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb
1471 1485
1472static 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)
1473{ 1487{
1488 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1489 struct hci_conn *conn;
1490
1474 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);
1475} 1503}
1476 1504
1477static 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)
@@ -1481,7 +1509,21 @@ static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff
1481 1509
1482static 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)
1483{ 1511{
1512 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1513 struct hci_conn *conn;
1514
1484 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);
1485} 1527}
1486 1528
1487static 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)
@@ -1646,20 +1688,28 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
1646 conn->type = SCO_LINK; 1688 conn->type = SCO_LINK;
1647 } 1689 }
1648 1690
1649 if (conn->out && ev->status == 0x1c && conn->attempt < 2) { 1691 switch (ev->status) {
1650 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) | 1692 case 0x00:
1651 (hdev->esco_type & EDR_ESCO_MASK);
1652 hci_setup_sync(conn, conn->link->handle);
1653 goto unlock;
1654 }
1655
1656 if (!ev->status) {
1657 conn->handle = __le16_to_cpu(ev->handle); 1693 conn->handle = __le16_to_cpu(ev->handle);
1658 conn->state = BT_CONNECTED; 1694 conn->state = BT_CONNECTED;
1659 1695
1660 hci_conn_add_sysfs(conn); 1696 hci_conn_add_sysfs(conn);
1661 } else 1697 break;
1698
1699 case 0x1c: /* SCO interval rejected */
1700 case 0x1f: /* Unspecified error */
1701 if (conn->out && conn->attempt < 2) {
1702 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1703 (hdev->esco_type & EDR_ESCO_MASK);
1704 hci_setup_sync(conn, conn->link->handle);
1705 goto unlock;
1706 }
1707 /* fall through */
1708
1709 default:
1662 conn->state = BT_CLOSED; 1710 conn->state = BT_CLOSED;
1711 break;
1712 }
1663 1713
1664 hci_proto_connect_cfm(conn, ev->status); 1714 hci_proto_connect_cfm(conn, ev->status);
1665 if (ev->status) 1715 if (ev->status)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ed82796d4a0f..582d8877078c 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 *bt_workq;
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 del is complete */
93 flush_work(&conn->work_del);
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");
@@ -98,27 +98,6 @@ static void add_conn(struct work_struct *work)
98 } 98 }
99} 99}
100 100
101void hci_conn_add_sysfs(struct hci_conn *conn)
102{
103 struct hci_dev *hdev = conn->hdev;
104
105 BT_DBG("conn %p", conn);
106
107 conn->dev.type = &bt_link;
108 conn->dev.class = bt_class;
109 conn->dev.parent = &hdev->dev;
110
111 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
112
113 dev_set_drvdata(&conn->dev, conn);
114
115 device_initialize(&conn->dev);
116
117 INIT_WORK(&conn->work, add_conn);
118
119 queue_work(btaddconn, &conn->work);
120}
121
122/* 101/*
123 * The rfcomm tty device will possibly retain even when conn 102 * The rfcomm tty device will possibly retain even when conn
124 * is down, and sysfs doesn't support move zombie device, 103 * is down, and sysfs doesn't support move zombie device,
@@ -131,9 +110,15 @@ static int __match_tty(struct device *dev, void *data)
131 110
132static void del_conn(struct work_struct *work) 111static void del_conn(struct work_struct *work)
133{ 112{
134 struct hci_conn *conn = container_of(work, struct hci_conn, work); 113 struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
135 struct hci_dev *hdev = conn->hdev; 114 struct hci_dev *hdev = conn->hdev;
136 115
116 /* ensure previous add is complete */
117 flush_work(&conn->work_add);
118
119 if (!device_is_registered(&conn->dev))
120 return;
121
137 while (1) { 122 while (1) {
138 struct device *dev; 123 struct device *dev;
139 124
@@ -149,16 +134,40 @@ static void del_conn(struct work_struct *work)
149 hci_dev_put(hdev); 134 hci_dev_put(hdev);
150} 135}
151 136
152void hci_conn_del_sysfs(struct hci_conn *conn) 137void hci_conn_init_sysfs(struct hci_conn *conn)
153{ 138{
139 struct hci_dev *hdev = conn->hdev;
140
154 BT_DBG("conn %p", conn); 141 BT_DBG("conn %p", conn);
155 142
156 if (!device_is_registered(&conn->dev)) 143 conn->dev.type = &bt_link;
157 return; 144 conn->dev.class = bt_class;
145 conn->dev.parent = &hdev->dev;
146
147 dev_set_drvdata(&conn->dev, conn);
148
149 device_initialize(&conn->dev);
150
151 INIT_WORK(&conn->work_add, add_conn);
152 INIT_WORK(&conn->work_del, del_conn);
153}
154
155void hci_conn_add_sysfs(struct hci_conn *conn)
156{
157 struct hci_dev *hdev = conn->hdev;
158
159 BT_DBG("conn %p", conn);
158 160
159 INIT_WORK(&conn->work, del_conn); 161 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
160 162
161 queue_work(btdelconn, &conn->work); 163 queue_work(bt_workq, &conn->work_add);
164}
165
166void hci_conn_del_sysfs(struct hci_conn *conn)
167{
168 BT_DBG("conn %p", conn);
169
170 queue_work(bt_workq, &conn->work_del);
162} 171}
163 172
164static inline char *host_typetostr(int type) 173static inline char *host_typetostr(int type)
@@ -435,20 +444,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
435 444
436int __init bt_sysfs_init(void) 445int __init bt_sysfs_init(void)
437{ 446{
438 btaddconn = create_singlethread_workqueue("btaddconn"); 447 bt_workq = create_singlethread_workqueue("bluetooth");
439 if (!btaddconn) 448 if (!bt_workq)
440 return -ENOMEM; 449 return -ENOMEM;
441 450
442 btdelconn = create_singlethread_workqueue("btdelconn");
443 if (!btdelconn) {
444 destroy_workqueue(btaddconn);
445 return -ENOMEM;
446 }
447
448 bt_class = class_create(THIS_MODULE, "bluetooth"); 451 bt_class = class_create(THIS_MODULE, "bluetooth");
449 if (IS_ERR(bt_class)) { 452 if (IS_ERR(bt_class)) {
450 destroy_workqueue(btdelconn); 453 destroy_workqueue(bt_workq);
451 destroy_workqueue(btaddconn);
452 return PTR_ERR(bt_class); 454 return PTR_ERR(bt_class);
453 } 455 }
454 456
@@ -457,8 +459,7 @@ int __init bt_sysfs_init(void)
457 459
458void bt_sysfs_cleanup(void) 460void bt_sysfs_cleanup(void)
459{ 461{
460 destroy_workqueue(btaddconn); 462 destroy_workqueue(bt_workq);
461 destroy_workqueue(btdelconn);
462 463
463 class_destroy(bt_class); 464 class_destroy(bt_class);
464} 465}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 1d0fb0f23c63..374536e050aa 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1194,6 +1194,8 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d)
1194 1194
1195 rfcomm_send_ua(d->session, d->dlci); 1195 rfcomm_send_ua(d->session, d->dlci);
1196 1196
1197 rfcomm_dlc_clear_timer(d);
1198
1197 rfcomm_dlc_lock(d); 1199 rfcomm_dlc_lock(d);
1198 d->state = BT_CONNECTED; 1200 d->state = BT_CONNECTED;
1199 d->state_change(d, 0); 1201 d->state_change(d, 0);