diff options
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 87 |
1 files changed, 44 insertions, 43 deletions
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 @@ | |||
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,9 +87,10 @@ 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); |
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 | ||
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 | |||
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 | ||
132 | static void del_conn(struct work_struct *work) | 111 | static 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 | ||
152 | void hci_conn_del_sysfs(struct hci_conn *conn) | 137 | void 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 | |||
155 | void 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 | |||
166 | void 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 | ||
164 | static inline char *host_typetostr(int type) | 173 | static inline char *host_typetostr(int type) |
@@ -435,20 +444,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev) | |||
435 | 444 | ||
436 | int __init bt_sysfs_init(void) | 445 | int __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 | ||
458 | void bt_sysfs_cleanup(void) | 460 | void 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 | } |