diff options
Diffstat (limited to 'net/bluetooth/hci_sysfs.c')
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 3ccb4b0b8fc2..58df4360d242 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -170,6 +170,32 @@ static struct device_attribute *bt_attrs[] = { | |||
170 | NULL | 170 | NULL |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | struct hci_conn *conn = dev_get_drvdata(dev); | ||
176 | return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO"); | ||
177 | } | ||
178 | |||
179 | static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf) | ||
180 | { | ||
181 | struct hci_conn *conn = dev_get_drvdata(dev); | ||
182 | bdaddr_t bdaddr; | ||
183 | baswap(&bdaddr, &conn->dst); | ||
184 | return sprintf(buf, "%s\n", batostr(&bdaddr)); | ||
185 | } | ||
186 | |||
187 | #define CONN_ATTR(_name,_mode,_show,_store) \ | ||
188 | struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store) | ||
189 | |||
190 | static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL); | ||
191 | static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL); | ||
192 | |||
193 | static struct device_attribute *conn_attrs[] = { | ||
194 | &conn_attr_type, | ||
195 | &conn_attr_address, | ||
196 | NULL | ||
197 | }; | ||
198 | |||
173 | struct class *bt_class = NULL; | 199 | struct class *bt_class = NULL; |
174 | EXPORT_SYMBOL_GPL(bt_class); | 200 | EXPORT_SYMBOL_GPL(bt_class); |
175 | 201 | ||
@@ -181,8 +207,57 @@ static struct platform_device *bt_platform; | |||
181 | 207 | ||
182 | static void bt_release(struct device *dev) | 208 | static void bt_release(struct device *dev) |
183 | { | 209 | { |
184 | struct hci_dev *hdev = dev_get_drvdata(dev); | 210 | void *data = dev_get_drvdata(dev); |
185 | kfree(hdev); | 211 | kfree(data); |
212 | } | ||
213 | |||
214 | static void add_conn(void *data) | ||
215 | { | ||
216 | struct hci_conn *conn = data; | ||
217 | int i; | ||
218 | |||
219 | device_register(&conn->dev); | ||
220 | |||
221 | for (i = 0; conn_attrs[i]; i++) | ||
222 | device_create_file(&conn->dev, conn_attrs[i]); | ||
223 | } | ||
224 | |||
225 | void hci_conn_add_sysfs(struct hci_conn *conn) | ||
226 | { | ||
227 | struct hci_dev *hdev = conn->hdev; | ||
228 | bdaddr_t *ba = &conn->dst; | ||
229 | |||
230 | BT_DBG("conn %p", conn); | ||
231 | |||
232 | conn->dev.parent = &hdev->dev; | ||
233 | conn->dev.release = bt_release; | ||
234 | |||
235 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, | ||
236 | "%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", | ||
237 | conn->type == ACL_LINK ? "acl" : "sco", | ||
238 | ba->b[5], ba->b[4], ba->b[3], | ||
239 | ba->b[2], ba->b[1], ba->b[0]); | ||
240 | |||
241 | dev_set_drvdata(&conn->dev, conn); | ||
242 | |||
243 | INIT_WORK(&conn->work, add_conn, (void *) conn); | ||
244 | |||
245 | schedule_work(&conn->work); | ||
246 | } | ||
247 | |||
248 | static void del_conn(void *data) | ||
249 | { | ||
250 | struct hci_conn *conn = data; | ||
251 | device_del(&conn->dev); | ||
252 | } | ||
253 | |||
254 | void hci_conn_del_sysfs(struct hci_conn *conn) | ||
255 | { | ||
256 | BT_DBG("conn %p", conn); | ||
257 | |||
258 | INIT_WORK(&conn->work, del_conn, (void *) conn); | ||
259 | |||
260 | schedule_work(&conn->work); | ||
186 | } | 261 | } |
187 | 262 | ||
188 | int hci_register_sysfs(struct hci_dev *hdev) | 263 | int hci_register_sysfs(struct hci_dev *hdev) |