diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 74 |
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 | ||
458 | int hci_register_sysfs(struct hci_dev *hdev); | 458 | int hci_register_sysfs(struct hci_dev *hdev); |
459 | void hci_unregister_sysfs(struct hci_dev *hdev); | 459 | void hci_unregister_sysfs(struct hci_dev *hdev); |
460 | void hci_conn_init_sysfs(struct hci_conn *conn); | ||
460 | void hci_conn_add_sysfs(struct hci_conn *conn); | 461 | void hci_conn_add_sysfs(struct hci_conn *conn); |
461 | void hci_conn_del_sysfs(struct hci_conn *conn); | 462 | void 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 @@ | |||
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 *bluetooth; | 12 | static struct workqueue_struct *bt_workq; |
13 | 13 | ||
14 | static inline char *link_typetostr(int type) | 14 | static 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 | ||
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, 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 | ||
155 | void hci_conn_del_sysfs(struct hci_conn *conn) | 137 | void 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 | |||
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); | ||
160 | |||
161 | dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); | ||
162 | |||
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); | ||
163 | 169 | ||
164 | queue_work(bluetooth, &conn->work_del); | 170 | queue_work(bt_workq, &conn->work_del); |
165 | } | 171 | } |
166 | 172 | ||
167 | static inline char *host_typetostr(int type) | 173 | static inline char *host_typetostr(int type) |
@@ -438,13 +444,13 @@ void hci_unregister_sysfs(struct hci_dev *hdev) | |||
438 | 444 | ||
439 | int __init bt_sysfs_init(void) | 445 | int __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 | ||
454 | void bt_sysfs_cleanup(void) | 460 | void 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 | } |