diff options
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 81 |
1 files changed, 39 insertions, 42 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index ed82796d4a0f..95f7a7a544b4 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,17 @@ 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 | 92 | ||
93 | flush_workqueue(btdelconn); | 93 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); |
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"); |
97 | return; | 97 | return; |
98 | } | 98 | } |
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 | 99 | ||
111 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | 100 | hci_dev_hold(hdev); |
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 | } | 101 | } |
121 | 102 | ||
122 | /* | 103 | /* |
@@ -131,9 +112,12 @@ static int __match_tty(struct device *dev, void *data) | |||
131 | 112 | ||
132 | static void del_conn(struct work_struct *work) | 113 | static void del_conn(struct work_struct *work) |
133 | { | 114 | { |
134 | struct hci_conn *conn = container_of(work, struct hci_conn, work); | 115 | struct hci_conn *conn = container_of(work, struct hci_conn, work_del); |
135 | struct hci_dev *hdev = conn->hdev; | 116 | struct hci_dev *hdev = conn->hdev; |
136 | 117 | ||
118 | if (!device_is_registered(&conn->dev)) | ||
119 | return; | ||
120 | |||
137 | while (1) { | 121 | while (1) { |
138 | struct device *dev; | 122 | struct device *dev; |
139 | 123 | ||
@@ -146,19 +130,40 @@ static void del_conn(struct work_struct *work) | |||
146 | 130 | ||
147 | device_del(&conn->dev); | 131 | device_del(&conn->dev); |
148 | put_device(&conn->dev); | 132 | put_device(&conn->dev); |
133 | |||
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; | ||
158 | 146 | ||
159 | INIT_WORK(&conn->work, del_conn); | 147 | dev_set_drvdata(&conn->dev, conn); |
148 | |||
149 | device_initialize(&conn->dev); | ||
160 | 150 | ||
161 | queue_work(btdelconn, &conn->work); | 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 | BT_DBG("conn %p", conn); | ||
158 | |||
159 | queue_work(bt_workq, &conn->work_add); | ||
160 | } | ||
161 | |||
162 | void hci_conn_del_sysfs(struct hci_conn *conn) | ||
163 | { | ||
164 | BT_DBG("conn %p", conn); | ||
165 | |||
166 | queue_work(bt_workq, &conn->work_del); | ||
162 | } | 167 | } |
163 | 168 | ||
164 | static inline char *host_typetostr(int type) | 169 | static inline char *host_typetostr(int type) |
@@ -435,20 +440,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev) | |||
435 | 440 | ||
436 | int __init bt_sysfs_init(void) | 441 | int __init bt_sysfs_init(void) |
437 | { | 442 | { |
438 | btaddconn = create_singlethread_workqueue("btaddconn"); | 443 | bt_workq = create_singlethread_workqueue("bluetooth"); |
439 | if (!btaddconn) | 444 | if (!bt_workq) |
440 | return -ENOMEM; | 445 | return -ENOMEM; |
441 | 446 | ||
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"); | 447 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
449 | if (IS_ERR(bt_class)) { | 448 | if (IS_ERR(bt_class)) { |
450 | destroy_workqueue(btdelconn); | 449 | destroy_workqueue(bt_workq); |
451 | destroy_workqueue(btaddconn); | ||
452 | return PTR_ERR(bt_class); | 450 | return PTR_ERR(bt_class); |
453 | } | 451 | } |
454 | 452 | ||
@@ -457,8 +455,7 @@ int __init bt_sysfs_init(void) | |||
457 | 455 | ||
458 | void bt_sysfs_cleanup(void) | 456 | void bt_sysfs_cleanup(void) |
459 | { | 457 | { |
460 | destroy_workqueue(btaddconn); | 458 | destroy_workqueue(bt_workq); |
461 | destroy_workqueue(btdelconn); | ||
462 | 459 | ||
463 | class_destroy(bt_class); | 460 | class_destroy(bt_class); |
464 | } | 461 | } |