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 | } |
