aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorDave Young <hidave.darkstar@gmail.com>2008-01-30 00:14:08 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:12 -0500
commitb6c0632105f7d7548f1d642ba830088478d4f2b0 (patch)
tree63e06f0d8565e5704d3ebabfd1597ad995253434 /net/bluetooth
parent2614fa59fa805cd488083c5602eb48533cdbc018 (diff)
[BLUETOOTH]: Add conn add/del workqueues to avoid connection fail.
The bluetooth hci_conn sysfs add/del executed in the default workqueue. If the del_conn is executed after the new add_conn with same target, add_conn will failed with warning of "same kobject name". Here add btaddconn & btdelconn workqueues, flush the btdelconn workqueue in the add_conn function to avoid the issue. Signed-off-by: Dave Young <hidave.darkstar@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_sysfs.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 17f7fb72055..2726adc419d 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -12,6 +12,8 @@
12#undef BT_DBG 12#undef BT_DBG
13#define BT_DBG(D...) 13#define BT_DBG(D...)
14#endif 14#endif
15static struct workqueue_struct *btaddconn;
16static struct workqueue_struct *btdelconn;
15 17
16static inline char *typetostr(int type) 18static inline char *typetostr(int type)
17{ 19{
@@ -279,6 +281,7 @@ static void add_conn(struct work_struct *work)
279 struct hci_conn *conn = container_of(work, struct hci_conn, work); 281 struct hci_conn *conn = container_of(work, struct hci_conn, work);
280 int i; 282 int i;
281 283
284 flush_workqueue(btdelconn);
282 if (device_add(&conn->dev) < 0) { 285 if (device_add(&conn->dev) < 0) {
283 BT_ERR("Failed to register connection device"); 286 BT_ERR("Failed to register connection device");
284 return; 287 return;
@@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
313 316
314 INIT_WORK(&conn->work, add_conn); 317 INIT_WORK(&conn->work, add_conn);
315 318
319 queue_work(btaddconn, &conn->work);
316 schedule_work(&conn->work); 320 schedule_work(&conn->work);
317} 321}
318 322
@@ -349,6 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
349 353
350 INIT_WORK(&conn->work, del_conn); 354 INIT_WORK(&conn->work, del_conn);
351 355
356 queue_work(btdelconn, &conn->work);
352 schedule_work(&conn->work); 357 schedule_work(&conn->work);
353} 358}
354 359
@@ -398,31 +403,52 @@ int __init bt_sysfs_init(void)
398{ 403{
399 int err; 404 int err;
400 405
406 btaddconn = create_singlethread_workqueue("btaddconn");
407 if (!btaddconn) {
408 err = -ENOMEM;
409 goto out;
410 }
411 btdelconn = create_singlethread_workqueue("btdelconn");
412 if (!btdelconn) {
413 err = -ENOMEM;
414 goto out_del;
415 }
416
401 bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0); 417 bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
402 if (IS_ERR(bt_platform)) 418 if (IS_ERR(bt_platform)) {
403 return PTR_ERR(bt_platform); 419 err = PTR_ERR(bt_platform);
420 goto out_platform;
421 }
404 422
405 err = bus_register(&bt_bus); 423 err = bus_register(&bt_bus);
406 if (err < 0) { 424 if (err < 0)
407 platform_device_unregister(bt_platform); 425 goto out_bus;
408 return err;
409 }
410 426
411 bt_class = class_create(THIS_MODULE, "bluetooth"); 427 bt_class = class_create(THIS_MODULE, "bluetooth");
412 if (IS_ERR(bt_class)) { 428 if (IS_ERR(bt_class)) {
413 bus_unregister(&bt_bus); 429 err = PTR_ERR(bt_class);
414 platform_device_unregister(bt_platform); 430 goto out_class;
415 return PTR_ERR(bt_class);
416 } 431 }
417 432
418 return 0; 433 return 0;
434
435out_class:
436 bus_unregister(&bt_bus);
437out_bus:
438 platform_device_unregister(bt_platform);
439out_platform:
440 destroy_workqueue(btdelconn);
441out_del:
442 destroy_workqueue(btaddconn);
443out:
444 return err;
419} 445}
420 446
421void bt_sysfs_cleanup(void) 447void bt_sysfs_cleanup(void)
422{ 448{
449 destroy_workqueue(btaddconn);
450 destroy_workqueue(btdelconn);
423 class_destroy(bt_class); 451 class_destroy(bt_class);
424
425 bus_unregister(&bt_bus); 452 bus_unregister(&bt_bus);
426
427 platform_device_unregister(bt_platform); 453 platform_device_unregister(bt_platform);
428} 454}