diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
commit | e4b636366c00738b9609cda307014d71b1225b7f (patch) | |
tree | 760b67b3624eda62e943e48ce93635c30a5b47bf /net/bluetooth | |
parent | b9ed7252d219c1c663944bf03846eabb515dbe75 (diff) | |
parent | 279e677faa775ad16e75c32e1bf4a37f8158bc61 (diff) |
Merge branch 'master' into for-2.6.31
Conflicts:
drivers/block/hd.c
drivers/block/mg_disk.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_conn.c | 18 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 36 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 87 |
3 files changed, 89 insertions, 52 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 1181db08d9de..fa47d5d84f5c 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -171,10 +171,8 @@ static void hci_conn_timeout(unsigned long arg) | |||
171 | switch (conn->state) { | 171 | switch (conn->state) { |
172 | case BT_CONNECT: | 172 | case BT_CONNECT: |
173 | case BT_CONNECT2: | 173 | case BT_CONNECT2: |
174 | if (conn->type == ACL_LINK) | 174 | if (conn->type == ACL_LINK && conn->out) |
175 | hci_acl_connect_cancel(conn); | 175 | hci_acl_connect_cancel(conn); |
176 | else | ||
177 | hci_acl_disconn(conn, 0x13); | ||
178 | break; | 176 | break; |
179 | case BT_CONFIG: | 177 | case BT_CONFIG: |
180 | case BT_CONNECTED: | 178 | case BT_CONNECTED: |
@@ -215,6 +213,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
215 | conn->state = BT_OPEN; | 213 | conn->state = BT_OPEN; |
216 | 214 | ||
217 | conn->power_save = 1; | 215 | conn->power_save = 1; |
216 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
218 | 217 | ||
219 | switch (type) { | 218 | switch (type) { |
220 | case ACL_LINK: | 219 | case ACL_LINK: |
@@ -247,6 +246,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
247 | if (hdev->notify) | 246 | if (hdev->notify) |
248 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); | 247 | hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); |
249 | 248 | ||
249 | hci_conn_init_sysfs(conn); | ||
250 | |||
250 | tasklet_enable(&hdev->tx_task); | 251 | tasklet_enable(&hdev->tx_task); |
251 | 252 | ||
252 | return conn; | 253 | return conn; |
@@ -289,6 +290,8 @@ int hci_conn_del(struct hci_conn *conn) | |||
289 | 290 | ||
290 | hci_conn_del_sysfs(conn); | 291 | hci_conn_del_sysfs(conn); |
291 | 292 | ||
293 | hci_dev_put(hdev); | ||
294 | |||
292 | return 0; | 295 | return 0; |
293 | } | 296 | } |
294 | 297 | ||
@@ -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 15f40ea8d544..184ba0a88ec0 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 | ||
1480 | static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1486 | static 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 && conn->state == BT_CONNECTED) { | ||
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 | ||
1485 | static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1505 | static 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 | ||
1490 | static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1510 | static 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 | ||
1495 | static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1529 | static 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..4cc3624bd22d 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -9,8 +9,7 @@ | |||
9 | struct class *bt_class = NULL; | 9 | struct class *bt_class = NULL; |
10 | EXPORT_SYMBOL_GPL(bt_class); | 10 | EXPORT_SYMBOL_GPL(bt_class); |
11 | 11 | ||
12 | static struct workqueue_struct *btaddconn; | 12 | static struct workqueue_struct *bt_workq; |
13 | static struct workqueue_struct *btdelconn; | ||
14 | 13 | ||
15 | static inline char *link_typetostr(int type) | 14 | static inline char *link_typetostr(int type) |
16 | { | 15 | { |
@@ -88,35 +87,20 @@ static struct device_type bt_link = { | |||
88 | 87 | ||
89 | static void add_conn(struct work_struct *work) | 88 | static 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); |
91 | struct hci_dev *hdev = conn->hdev; | ||
92 | |||
93 | /* ensure previous del is complete */ | ||
94 | flush_work(&conn->work_del); | ||
92 | 95 | ||
93 | flush_workqueue(btdelconn); | 96 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
94 | 97 | ||
95 | if (device_add(&conn->dev) < 0) { | 98 | if (device_add(&conn->dev) < 0) { |
96 | BT_ERR("Failed to register connection device"); | 99 | BT_ERR("Failed to register connection device"); |
97 | return; | 100 | return; |
98 | } | 101 | } |
99 | } | ||
100 | |||
101 | void 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 | 102 | ||
117 | INIT_WORK(&conn->work, add_conn); | 103 | hci_dev_hold(hdev); |
118 | |||
119 | queue_work(btaddconn, &conn->work); | ||
120 | } | 104 | } |
121 | 105 | ||
122 | /* | 106 | /* |
@@ -131,9 +115,15 @@ static int __match_tty(struct device *dev, void *data) | |||
131 | 115 | ||
132 | static void del_conn(struct work_struct *work) | 116 | static void del_conn(struct work_struct *work) |
133 | { | 117 | { |
134 | struct hci_conn *conn = container_of(work, struct hci_conn, work); | 118 | struct hci_conn *conn = container_of(work, struct hci_conn, work_del); |
135 | struct hci_dev *hdev = conn->hdev; | 119 | struct hci_dev *hdev = conn->hdev; |
136 | 120 | ||
121 | /* ensure previous add is complete */ | ||
122 | flush_work(&conn->work_add); | ||
123 | |||
124 | if (!device_is_registered(&conn->dev)) | ||
125 | return; | ||
126 | |||
137 | while (1) { | 127 | while (1) { |
138 | struct device *dev; | 128 | struct device *dev; |
139 | 129 | ||
@@ -146,19 +136,40 @@ static void del_conn(struct work_struct *work) | |||
146 | 136 | ||
147 | device_del(&conn->dev); | 137 | device_del(&conn->dev); |
148 | put_device(&conn->dev); | 138 | put_device(&conn->dev); |
139 | |||
149 | hci_dev_put(hdev); | 140 | hci_dev_put(hdev); |
150 | } | 141 | } |
151 | 142 | ||
152 | void hci_conn_del_sysfs(struct hci_conn *conn) | 143 | void hci_conn_init_sysfs(struct hci_conn *conn) |
153 | { | 144 | { |
145 | struct hci_dev *hdev = conn->hdev; | ||
146 | |||
154 | BT_DBG("conn %p", conn); | 147 | BT_DBG("conn %p", conn); |
155 | 148 | ||
156 | if (!device_is_registered(&conn->dev)) | 149 | conn->dev.type = &bt_link; |
157 | return; | 150 | conn->dev.class = bt_class; |
151 | conn->dev.parent = &hdev->dev; | ||
152 | |||
153 | dev_set_drvdata(&conn->dev, conn); | ||
154 | |||
155 | device_initialize(&conn->dev); | ||
156 | |||
157 | INIT_WORK(&conn->work_add, add_conn); | ||
158 | INIT_WORK(&conn->work_del, del_conn); | ||
159 | } | ||
158 | 160 | ||
159 | INIT_WORK(&conn->work, del_conn); | 161 | void hci_conn_add_sysfs(struct hci_conn *conn) |
162 | { | ||
163 | BT_DBG("conn %p", conn); | ||
160 | 164 | ||
161 | queue_work(btdelconn, &conn->work); | 165 | queue_work(bt_workq, &conn->work_add); |
166 | } | ||
167 | |||
168 | void hci_conn_del_sysfs(struct hci_conn *conn) | ||
169 | { | ||
170 | BT_DBG("conn %p", conn); | ||
171 | |||
172 | queue_work(bt_workq, &conn->work_del); | ||
162 | } | 173 | } |
163 | 174 | ||
164 | static inline char *host_typetostr(int type) | 175 | static inline char *host_typetostr(int type) |
@@ -435,20 +446,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev) | |||
435 | 446 | ||
436 | int __init bt_sysfs_init(void) | 447 | int __init bt_sysfs_init(void) |
437 | { | 448 | { |
438 | btaddconn = create_singlethread_workqueue("btaddconn"); | 449 | bt_workq = create_singlethread_workqueue("bluetooth"); |
439 | if (!btaddconn) | 450 | if (!bt_workq) |
440 | return -ENOMEM; | 451 | return -ENOMEM; |
441 | 452 | ||
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"); | 453 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
449 | if (IS_ERR(bt_class)) { | 454 | if (IS_ERR(bt_class)) { |
450 | destroy_workqueue(btdelconn); | 455 | destroy_workqueue(bt_workq); |
451 | destroy_workqueue(btaddconn); | ||
452 | return PTR_ERR(bt_class); | 456 | return PTR_ERR(bt_class); |
453 | } | 457 | } |
454 | 458 | ||
@@ -457,8 +461,7 @@ int __init bt_sysfs_init(void) | |||
457 | 461 | ||
458 | void bt_sysfs_cleanup(void) | 462 | void bt_sysfs_cleanup(void) |
459 | { | 463 | { |
460 | destroy_workqueue(btaddconn); | 464 | destroy_workqueue(bt_workq); |
461 | destroy_workqueue(btdelconn); | ||
462 | 465 | ||
463 | class_destroy(bt_class); | 466 | class_destroy(bt_class); |
464 | } | 467 | } |