aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_conn.c2
-rw-r--r--net/bluetooth/hci_sysfs.c74
3 files changed, 43 insertions, 34 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index be5bd713d2c9..73aead222b32 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -457,6 +457,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
457 457
458int hci_register_sysfs(struct hci_dev *hdev); 458int hci_register_sysfs(struct hci_dev *hdev);
459void hci_unregister_sysfs(struct hci_dev *hdev); 459void hci_unregister_sysfs(struct hci_dev *hdev);
460void hci_conn_init_sysfs(struct hci_conn *conn);
460void hci_conn_add_sysfs(struct hci_conn *conn); 461void hci_conn_add_sysfs(struct hci_conn *conn);
461void hci_conn_del_sysfs(struct hci_conn *conn); 462void hci_conn_del_sysfs(struct hci_conn *conn);
462 463
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 375f4b4f7f79..61309b26f271 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -248,6 +248,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
248 if (hdev->notify) 248 if (hdev->notify)
249 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); 249 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
250 250
251 hci_conn_init_sysfs(conn);
252
251 tasklet_enable(&hdev->tx_task); 253 tasklet_enable(&hdev->tx_task);
252 254
253 return conn; 255 return conn;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index b7c51082ddeb..582d8877078c 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -9,7 +9,7 @@
9struct class *bt_class = NULL; 9struct class *bt_class = NULL;
10EXPORT_SYMBOL_GPL(bt_class); 10EXPORT_SYMBOL_GPL(bt_class);
11 11
12static struct workqueue_struct *bluetooth; 12static struct workqueue_struct *bt_workq;
13 13
14static inline char *link_typetostr(int type) 14static inline char *link_typetostr(int type)
15{ 15{
@@ -89,8 +89,8 @@ static void add_conn(struct work_struct *work)
89{ 89{
90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add); 90 struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
91 91
92 /* ensure previous add/del is complete */ 92 /* ensure previous del is complete */
93 flush_workqueue(bluetooth); 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
101void 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, add_conn);
118
119 queue_work(bluetooth, &conn->work_add);
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,
@@ -134,8 +113,11 @@ static void del_conn(struct work_struct *work)
134 struct hci_conn *conn = container_of(work, struct hci_conn, work_del); 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
137 /* ensure previous add/del is complete */ 116 /* ensure previous add is complete */
138 flush_workqueue(bluetooth); 117 flush_work(&conn->work_add);
118
119 if (!device_is_registered(&conn->dev))
120 return;
139 121
140 while (1) { 122 while (1) {
141 struct device *dev; 123 struct device *dev;
@@ -152,16 +134,40 @@ static void del_conn(struct work_struct *work)
152 hci_dev_put(hdev); 134 hci_dev_put(hdev);
153} 135}
154 136
155void hci_conn_del_sysfs(struct hci_conn *conn) 137void hci_conn_init_sysfs(struct hci_conn *conn)
156{ 138{
139 struct hci_dev *hdev = conn->hdev;
140
157 BT_DBG("conn %p", conn); 141 BT_DBG("conn %p", conn);
158 142
159 if (!device_is_registered(&conn->dev)) 143 conn->dev.type = &bt_link;
160 return; 144 conn->dev.class = bt_class;
145 conn->dev.parent = &hdev->dev;
146
147 dev_set_drvdata(&conn->dev, conn);
161 148
149 device_initialize(&conn->dev);
150
151 INIT_WORK(&conn->work_add, add_conn);
162 INIT_WORK(&conn->work_del, del_conn); 152 INIT_WORK(&conn->work_del, del_conn);
153}
154
155void hci_conn_add_sysfs(struct hci_conn *conn)
156{
157 struct hci_dev *hdev = conn->hdev;
158
159 BT_DBG("conn %p", conn);
160
161 dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
162
163 queue_work(bt_workq, &conn->work_add);
164}
165
166void hci_conn_del_sysfs(struct hci_conn *conn)
167{
168 BT_DBG("conn %p", conn);
163 169
164 queue_work(bluetooth, &conn->work_del); 170 queue_work(bt_workq, &conn->work_del);
165} 171}
166 172
167static inline char *host_typetostr(int type) 173static inline char *host_typetostr(int type)
@@ -438,13 +444,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
438 444
439int __init bt_sysfs_init(void) 445int __init bt_sysfs_init(void)
440{ 446{
441 bluetooth = create_singlethread_workqueue("bluetooth"); 447 bt_workq = create_singlethread_workqueue("bluetooth");
442 if (!bluetooth) 448 if (!bt_workq)
443 return -ENOMEM; 449 return -ENOMEM;
444 450
445 bt_class = class_create(THIS_MODULE, "bluetooth"); 451 bt_class = class_create(THIS_MODULE, "bluetooth");
446 if (IS_ERR(bt_class)) { 452 if (IS_ERR(bt_class)) {
447 destroy_workqueue(bluetooth); 453 destroy_workqueue(bt_workq);
448 return PTR_ERR(bt_class); 454 return PTR_ERR(bt_class);
449 } 455 }
450 456
@@ -453,7 +459,7 @@ int __init bt_sysfs_init(void)
453 459
454void bt_sysfs_cleanup(void) 460void bt_sysfs_cleanup(void)
455{ 461{
456 destroy_workqueue(bluetooth); 462 destroy_workqueue(bt_workq);
457 463
458 class_destroy(bt_class); 464 class_destroy(bt_class);
459} 465}