Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b6c0632105f7d7548f1d642ba830088478d4f2b0
Commit:     b6c0632105f7d7548f1d642ba830088478d4f2b0
Parent:     2614fa59fa805cd488083c5602eb48533cdbc018
Author:     Dave Young <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 29 21:14:08 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Thu Jan 31 19:27:12 2008 -0800

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/bluetooth/hci_sysfs.c |   48 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 17f7fb7..2726adc 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -12,6 +12,8 @@
 #undef  BT_DBG
 #define BT_DBG(D...)
 #endif
+static struct workqueue_struct *btaddconn;
+static struct workqueue_struct *btdelconn;
 
 static inline char *typetostr(int type)
 {
@@ -279,6 +281,7 @@ static void add_conn(struct work_struct *work)
        struct hci_conn *conn = container_of(work, struct hci_conn, work);
        int i;
 
+       flush_workqueue(btdelconn);
        if (device_add(&conn->dev) < 0) {
                BT_ERR("Failed to register connection device");
                return;
@@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
 
        INIT_WORK(&conn->work, add_conn);
 
+       queue_work(btaddconn, &conn->work);
        schedule_work(&conn->work);
 }
 
@@ -349,6 +353,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
 
        INIT_WORK(&conn->work, del_conn);
 
+       queue_work(btdelconn, &conn->work);
        schedule_work(&conn->work);
 }
 
@@ -398,31 +403,52 @@ int __init bt_sysfs_init(void)
 {
        int err;
 
+       btaddconn = create_singlethread_workqueue("btaddconn");
+       if (!btaddconn) {
+               err = -ENOMEM;
+               goto out;
+       }
+       btdelconn = create_singlethread_workqueue("btdelconn");
+       if (!btdelconn) {
+               err = -ENOMEM;
+               goto out_del;
+       }
+
        bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
-       if (IS_ERR(bt_platform))
-               return PTR_ERR(bt_platform);
+       if (IS_ERR(bt_platform)) {
+               err = PTR_ERR(bt_platform);
+               goto out_platform;
+       }
 
        err = bus_register(&bt_bus);
-       if (err < 0) {
-               platform_device_unregister(bt_platform);
-               return err;
-       }
+       if (err < 0)
+               goto out_bus;
 
        bt_class = class_create(THIS_MODULE, "bluetooth");
        if (IS_ERR(bt_class)) {
-               bus_unregister(&bt_bus);
-               platform_device_unregister(bt_platform);
-               return PTR_ERR(bt_class);
+               err = PTR_ERR(bt_class);
+               goto out_class;
        }
 
        return 0;
+
+out_class:
+       bus_unregister(&bt_bus);
+out_bus:
+       platform_device_unregister(bt_platform);
+out_platform:
+       destroy_workqueue(btdelconn);
+out_del:
+       destroy_workqueue(btaddconn);
+out:
+       return err;
 }
 
 void bt_sysfs_cleanup(void)
 {
+       destroy_workqueue(btaddconn);
+       destroy_workqueue(btdelconn);
        class_destroy(bt_class);
-
        bus_unregister(&bt_bus);
-
        platform_device_unregister(bt_platform);
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to